Wytyczne dotyczące obsługi indeksu pełnotekstowego

29

Jakie wytyczne należy wziąć pod uwagę przy utrzymywaniu indeksów pełnotekstowych?

Czy powinienem ODBUDOWAĆ lub REORGANIZOWAĆ katalog pełnotekstowy (patrz BOL )? Co to jest rozsądna kadencja konserwacyjna? Jaką heurystykę (podobną do 10% i 30% progów fragmentacji) można zastosować do ustalenia, kiedy konieczna jest konserwacja?

(Wszystko poniżej to po prostu dodatkowe informacje dotyczące pytania i pokazujące, o czym do tej pory myślałem.)



Dodatkowe informacje: moje pierwsze badania

Istnieje wiele zasobów na temat utrzymania indeksu b-drzewa (np. To pytanie , skrypty Oli Hallengren i liczne posty na blogu na ten temat z innych stron). Stwierdziłem jednak, że żaden z tych zasobów nie zawiera zaleceń ani skryptów do obsługi indeksów pełnotekstowych.

Jest dokumentacja Microsoft , który wspomina, że defragmentacji indeksu B-tree tabeli bazowej, a następnie przeprowadzenie reorganizacji w sprawie katalogu pełnotekstowego może poprawić wydajność, ale nie dotykać jakichkolwiek bardziej szczegółowych zaleceń.

Znalazłem również to pytanie , ale koncentruje się ono głównie na śledzeniu zmian (w jaki sposób aktualizacje danych w tabeli bazowej są propagowane do indeksu pełnotekstowego), a nie na typie regularnych przeglądów, które mogłyby zmaksymalizować wydajność indeksu.

Dodatkowe informacje: podstawowe testy wydajności

Ten SQL Fiddle zawiera kod, którego można użyć do utworzenia indeksu pełnotekstowego ze AUTOśledzeniem zmian oraz zbadania zarówno wielkości, jak i wydajności zapytania indeksu, gdy dane w tabeli są modyfikowane. Kiedy uruchamiam logikę skryptu na kopii moich danych produkcyjnych (w przeciwieństwie do sztucznie wytworzonych danych w skrzypcach), oto podsumowanie wyników, które widzę po każdym kroku modyfikacji danych:

wprowadź opis zdjęcia tutaj

Mimo że instrukcje aktualizacji w tym skrypcie były dość wymyślone, dane te wydają się wskazywać, że wiele można zyskać dzięki regularnej konserwacji.

Dodatkowe informacje: wstępne pomysły

Zastanawiam się nad stworzeniem zadania nocnego lub tygodniowego. Wygląda na to, że to zadanie może wykonać ODBUDOWANIE lub REORGANIZACJĘ.

Ponieważ indeksy pełnotekstowe mogą być dość duże (dziesiątki lub setki milionów wierszy), chciałbym być w stanie wykryć, kiedy indeksy w katalogu są wystarczająco podzielone, aby zagwarantować REBUILD / REORGANIZE. Jestem trochę niejasny, co heurystyka może mieć w tym sens.

Geoff Patterson
źródło

Odpowiedzi:

36

Nie byłem w stanie znaleźć żadnych dobrych zasobów online, więc przeprowadziłem więcej praktycznych badań i pomyślałem, że użyteczne byłoby opublikowanie wynikowego planu konserwacji pełnego tekstu, który wdrażamy na podstawie tych badań.


Nasza heurystyka określa, kiedy konieczna jest konserwacja

wprowadź opis zdjęcia tutaj

Naszym głównym celem jest utrzymanie stałej wydajności zapytań pełnotekstowych w miarę ewolucji danych w tabelach leżących u ich podstaw. Jednak z różnych powodów trudno byłoby nam każdego wieczora uruchamiać reprezentatywny zestaw zapytań pełnotekstowych dla każdej z naszych baz danych i wykorzystywać wydajność tych zapytań, aby określić, kiedy konieczna jest konserwacja. Dlatego chcieliśmy stworzyć praktyczne reguły, które można bardzo szybko obliczyć i wykorzystać jako heurystykę, aby wskazać, że utrzymanie indeksu pełnotekstowego może być uzasadnione.

W trakcie tej eksploracji stwierdziliśmy, że katalog systemowy zawiera wiele informacji na temat tego, w jaki sposób dany indeks pełnotekstowy jest dzielony na fragmenty. Jednak nie ma obliczonego oficjalnego „fragmentacji%” (tak jak w przypadku indeksów b-drzewa za pośrednictwem sys.dm_db_index_physical_stats ). Na podstawie informacji o fragmentach pełnego tekstu postanowiliśmy obliczyć własne „fragmentację pełnego tekstu%”. Następnie użyliśmy serwera deweloperów, aby wielokrotnie dokonywać losowych aktualizacji w dowolnym miejscu od 100 do 25 000 wierszy na raz do 10 milionów wierszy kopii danych produkcyjnych, rejestrować fragmentację pełnego tekstu i wykonywać wzorcowe zapytanie pełnotekstowe przy użyciu CONTAINSTABLE.

Wyniki, jak widać na wykresach powyżej i poniżej, były bardzo pouczające i pokazały, że stworzona przez nas miara fragmentacji jest bardzo silnie skorelowana z obserwowaną wydajnością. Ponieważ ma to również związek z naszymi jakościowymi obserwacjami podczas produkcji, wystarczy, że wygodnie jest nam używać procent fragmentacji jako naszej heurystyki przy podejmowaniu decyzji, kiedy nasze indeksy pełnotekstowe wymagają konserwacji.

wprowadź opis zdjęcia tutaj


Plan konserwacji

Zdecydowaliśmy się użyć następującego kodu do obliczenia% fragmentacji dla każdego indeksu pełnotekstowego. Wszelkie indeksy pełnotekstowe o nieistotnych rozmiarach z fragmentacją co najmniej 10% zostaną oflagowane, aby zostały odbudowane przez naszą nocną konserwację.

-- Compute fragmentation information for all full-text indexes on the database
SELECT c.fulltext_catalog_id, c.name AS fulltext_catalog_name, i.change_tracking_state,
    i.object_id, OBJECT_SCHEMA_NAME(i.object_id) + '.' + OBJECT_NAME(i.object_id) AS object_name,
    f.num_fragments, f.fulltext_mb, f.largest_fragment_mb,
    100.0 * (f.fulltext_mb - f.largest_fragment_mb) / NULLIF(f.fulltext_mb, 0) AS fulltext_fragmentation_in_percent
INTO #fulltextFragmentationDetails
FROM sys.fulltext_catalogs c
JOIN sys.fulltext_indexes i
    ON i.fulltext_catalog_id = c.fulltext_catalog_id
JOIN (
    -- Compute fragment data for each table with a full-text index
    SELECT table_id,
        COUNT(*) AS num_fragments,
        CONVERT(DECIMAL(9,2), SUM(data_size/(1024.*1024.))) AS fulltext_mb,
        CONVERT(DECIMAL(9,2), MAX(data_size/(1024.*1024.))) AS largest_fragment_mb
    FROM sys.fulltext_index_fragments
    GROUP BY table_id
) f
    ON f.table_id = i.object_id

-- Apply a basic heuristic to determine any full-text indexes that are "too fragmented"
-- We have chosen the 10% threshold based on performance benchmarking on our own data
-- Our over-night maintenance will then drop and re-create any such indexes
SELECT *
FROM #fulltextFragmentationDetails
WHERE fulltext_fragmentation_in_percent >= 10
    AND fulltext_mb >= 1 -- No need to bother with indexes of trivial size

Te zapytania dają wyniki takie jak poniżej, w tym przypadku wiersze 1, 6 i 9 zostałyby oznaczone jako zbyt pofragmentowane dla optymalnej wydajności, ponieważ indeks pełnotekstowy ma ponad 1 MB i co najmniej 10% fragmentacji.

wprowadź opis zdjęcia tutaj


Utrzymanie rytmu

Mamy już okno konserwacji nocnej, a obliczanie fragmentacji jest bardzo tanie. Będziemy więc przeprowadzać tę kontrolę co noc, a następnie wykonamy tylko droższą operację polegającą na przebudowaniu indeksu pełnotekstowego, gdy będzie to konieczne, w oparciu o próg fragmentacji 10%.


ODBUDOWAĆ vs REORGANIZACJA vs. ZROBIĆ / UTWÓRZ

Oferty REBUILDi REORGANIZEopcje programu SQL Server , ale są one dostępne tylko dla katalogu pełnotekstowego (który może zawierać dowolną liczbę indeksów pełnotekstowych) w całości. Ze względów starszych mamy jeden katalog pełnotekstowy, który zawiera wszystkie nasze indeksy pełnotekstowe. Dlatego zdecydowaliśmy się na drop ( DROP FULLTEXT INDEX), a następnie odtworzenie ( CREATE FULLTEXT INDEX) na poziomie indeksu pełnotekstowego.

Bardziej idealne może być podzielenie indeksów pełnotekstowych na osobne katalogi w logiczny sposób i wykonanie REBUILDzamiast nich, ale rozwiązanie drop / create będzie dla nas w międzyczasie działać.

Geoff Patterson
źródło