Indeks pełnotekstowy programu SQL Server 2008 nigdy się nie kończy

13

Nasza strona internetowa ma bazę danych SQL Server 2008 R2 Express Edition z indeksowaniem pełnotekstowym do wyszukiwania w naszej witrynie. Za każdym razem, gdy nowy rekord jest dodawany lub aktualizowany w jednej z indeksowanych tabel, proces indeksowania nigdy się nie kończy.

W ciągu ostatnich kilku tygodni monitorowałem status, używając zasadniczo tego samego zapytania znalezionego na tej stronie: http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-search/2155/Why-is-this -populacja-tak długo

Oto, co widzę po uruchomieniu zapytania (kliknij, aby wyświetlić pełny rozmiar): Status indeksu pełnotekstowego

Najnowsze rekordy w indeksowanych tabelach nigdy się nie kończą i nie można ich przeszukiwać. Mimo że w tabelach nie ma zbyt wielu danych, czekałem dni, aby sprawdzić, czy indeksowanie się zakończy, ale nic się nie zmienia.

Jedynym sposobem na pomyślne ukończenie indeksowania jest albo przebudowanie katalogu, albo usunięcie i ponowne utworzenie wszystkich indeksów.

Za każdym razem, gdy to robię, ten sam problem wraca, gdy tylko zostanie dodany pierwszy nowy rekord.

Oto statystyki serwera na wszelki wypadek:

  • Czterordzeniowy AMD Opteron 2,34 GHz
  • 4 GB pamięci RAM
  • Windows Server 2008 R2 Enterprise SP1 x64
  • SQL Server 2008 R2 Express Edition z zaawansowanymi usługami x64
Jargs
źródło

Odpowiedzi:

6

W końcu znalazłem przyczynę mojego problemu!

Przez miesiące próbowałem wyśledzić ten problem, ale w końcu zrezygnowałem, wyłączyłem automatyczne śledzenie zmian, po prostu ręcznie zainicjowałem przyrostową populację i ruszyłem z życiem.

W międzyczasie wystąpił kolejny dokuczliwy błąd, przez który miałem problemy ze śledzeniem. Okresowo witryna zgłaszała błąd połączenia z bazą danych:

Nie można otworzyć bazy danych „XXXX” wymaganej przez login. Logowanie nie powiodło się. Logowanie nie powiodło się dla użytkownika „XXXX”.

Okazało się, że oba te problemy miały to samo rozwiązanie. Wszystko, co musiałem zrobić, to wyłączyć ustawienie bazy danych o nazwie Auto Close. Aby to zrobić, kliknij prawym przyciskiem myszy bazę danych i kliknij właściwości. W oknie właściwości wybierz Opcje i ustaw „Automatyczne zamykanie” na false.

Okno właściwości bazy danych

Gdy tylko wyłączyłem funkcję automatycznego zamykania, problemy z logowaniem do bazy danych zniknęły, a automatyczne śledzenie zmian działało idealnie.

Jeszcze raz dziękuję za pomoc wszystkim. Doceniam to!

Jargs
źródło
3

Ciekawe, czy wykonałeś kroki rozwiązywania problemów w BOL dla wydajności pełnego tekstu - http://technet.microsoft.com/en-us/library/ms142560.aspx .

Założę się, że SQL Server zjada całą twoją pamięć i nie pozwala demonowi filtrującemu mieć jakąkolwiek, więc twoja populacja jest powolna, ponieważ najprawdopodobniej będzie musiał zamienić rzeczy na plik stronicowania. Powinieneś ograniczyć ilość pamięci, którą SQL może zużyć (pomyślałem, że około 3 GB, biorąc pod uwagę twoje obecne specyfikacje systemu - to zostawiłoby 1 GB dla FDHost i systemu operacyjnego).

Brandon
źródło
głosowanie w górę @Brandon. Przeczytaj tę sekcję: „Główną przyczyną zmniejszonej wydajności indeksowania pełnotekstowego są ograniczenia zasobów sprzętowych:”
MacGyver
2

Oto skrypt, który utworzyłem za pomocą kursorów, w celu przebudowania i wypełnienia pełnych indeksów dla dowolnej tabeli, która ma jeden dla MSSQL2008. Działa to w środowisku produkcyjnym z bazami danych migrowanymi z serwera MSSQL 2000. Wyłączyłem śledzenie zmian i po prostu uruchomiłem tę procedurę przechowywaną za pośrednictwem agenta SQL Server. Jeśli korzystasz z ekspresu, możesz użyć skryptu VBS, aby uruchomić go za pomocą Harmonogramu zadań.

Ważne było w skrypcie, aby najpierw przebudować każdy katalog przed zapełnieniem indeksów.

CREATE PROCEDURE [dbo].[rebuild_repopulate_fulltext] 
AS
BEGIN

Declare @cmdA NVARCHAR(255)
Declare @cmdB NVARCHAR(255)
Declare @cmdC NVARCHAR(255)
DECLARE @Database VARCHAR(255)   
DECLARE @Table VARCHAR(255)  
DECLARE @cmd NVARCHAR(500)  
DECLARE @fillfactor INT 
DECLARE @Catalog VARCHAR(255)
DECLARE @Schema VARCHAR(255)

SET @fillfactor = 90 

DECLARE DatabaseCursor CURSOR FOR  
SELECT name FROM MASTER.dbo.sysdatabases   
WHERE name NOT IN ('master','msdb','tempdb','model','distribution')   
ORDER BY 1  

OPEN DatabaseCursor  

FETCH NEXT FROM DatabaseCursor INTO @Database  
WHILE @@FETCH_STATUS = 0  
BEGIN  

   -- rebuild fulltext catalog
   set @cmd = 'DECLARE CatalogCursor CURSOR FOR 
        SELECT t.name AS TableName, c.name AS FTCatalogName, s.name as schemaname
        FROM ['+ @Database + '].sys.tables t JOIN ['+ @Database +'].sys.fulltext_indexes i
        ON t.object_id = i.object_id
        JOIN ['+ @Database + '].sys.fulltext_catalogs c
        ON i.fulltext_catalog_id = c.fulltext_catalog_id
        JOIN ['+ @Database + '].sys.schemas s ON t.schema_id = s.schema_id'
   --PRINT @cmd
   EXEC (@cmd)  


   OPEN CatalogCursor   

   FETCH NEXT FROM CatalogCursor INTO @Table, @Catalog, @Schema
   WHILE @@FETCH_STATUS = 0   
   BEGIN  

    SET @cmdB = 'USE ['+ @Database + ']; ALTER FULLTEXT CATALOG ' + @Catalog + ' REBUILD;'
    --PRINT @cmdB
    EXEC (@cmdB)


    FETCH NEXT FROM CatalogCursor INTO @Table, @Catalog, @Schema
   END   

   CLOSE CatalogCursor   


   OPEN CatalogCursor   

   FETCH NEXT FROM CatalogCursor INTO @Table, @Catalog, @Schema
   WHILE @@FETCH_STATUS = 0   
   BEGIN  

    SET @cmdC = 'USE ['+ @Database + ']; ALTER FULLTEXT INDEX ON ['+ @Database + '].[' + @Schema + '].[' + @Table + '] START FULL POPULATION;' 
    --PRINT @cmdC
    EXEC (@cmdC)

    FETCH NEXT FROM CatalogCursor INTO @Table, @Catalog, @Schema
   END   

   CLOSE CatalogCursor   
   DEALLOCATE CatalogCursor  



   FETCH NEXT FROM DatabaseCursor INTO @Database  
END  

CLOSE DatabaseCursor   
DEALLOCATE DatabaseCursor

END

Czy ktoś ma metodę, która nie wymaga kursorów?

Craig Efrein
źródło
0

Zwykle zaleca się aktualizację katalogu pełnotekstowego przy użyciu wyzwalaczy. Takiego podejścia używam na mssql, ale w moim przypadku, ponieważ mam zlokalizowaną aplikację z kilkoma konkretnymi wymaganiami, które prowadzą mnie do rozwiązania wykorzystującego wyzwalacze, że rozwiązania działają w 100% od 2 lat wstecz.

Przejrzyj swoją implementację na tym przykładzie .

Rui Marques
źródło
Obecnie moje indeksy są ustawione na automatyczne śledzenie zmian. Czytałem, że zmiana na ręczną i używanie wyzwalaczy może powodować problemy, gdy jedna osoba wstawi lub zaktualizuje rekord w indeksowanej tabeli, zanim wyzwalana aktualizacja indeksu z poprzedniej aktualizacji tabeli jeszcze się nie zakończyła. Wygląda na to, że automatyczne śledzenie zmian powinno działać ... zwłaszcza, że ​​nie mam tak wielu rekordów w moich tabelach.
Jargs
Sprawdziłem moją konfigurację pod kątem podanego przez Ciebie linku, ale wszystko wydaje się być w porządku. Próbowałem nawet naprawić instalację programu SQL Server, ale problem pozostaje.
Jargs,
1
Nie wiem, czy to jest powiązane, ale kiedyś miałem problem z populacją pełnego katalogu z powodu problemów z Word Breakerem. Jeśli otworzysz SSMS i wybierzesz Pamięć w bazie danych, kliknij katalog pełnotekstowy prawym przyciskiem myszy. Przejdź do tabel / widoków i spójrz na Language for Word Breaker. Czy istnieją kolumny używające różnych języków dla dzielników słów? Zauważyłem, że jeśli masz różne języki dla Word Breakerów w tej samej tabeli, populacja nie działa. Może niezwiązany, ale kto wie?
Craig Efrein
0

Nie wiesz, jaka jest główna przyczyna twojej sytuacji, ale może się to zdarzyć po wykonaniu kopii zapasowej. Nie jestem pewien, czy tak dzieje się w twoim przypadku, czy też ten stół różni się od innych. Teraz mnie ciekawi. Czy masz włączoną replikację SQL?

Aby tymczasowo naprawić, wykonam „indeksowanie” (populację) na stole, gdy to się stanie.

http://msdn.microsoft.com/en-us/library/ms142575(v=sql.105).aspx

Użyj tego kodu:

ALTER FULLTEXT INDEX ON dbname.dbo.tablename
START FULL POPULATION;
MacGyver
źródło