Linee guida per la manutenzione dell'indice full-text


29

Quali linee guida dovrebbero essere prese in considerazione per mantenere gli indici full-text?

Devo RICOSTRUIRE o RIORGANIZZARE il catalogo full-text (vedi BOL )? Cos'è una cadenza di manutenzione ragionevole? Quali euristiche (simili alle soglie di frammentazione del 10% e del 30%) potrebbero essere utilizzate per determinare quando è necessaria la manutenzione?

(Tutto sotto è semplicemente informazioni extra che elaborano la domanda e mostrano ciò a cui ho pensato finora.)



Informazioni extra: la mia ricerca iniziale

Ci sono molte risorse sulla manutenzione dell'indice b-tree (ad esempio, questa domanda , gli script di Ola Hallengren e numerosi post di blog sull'argomento da altri siti). Tuttavia, ho scoperto che nessuna di queste risorse fornisce consigli o script per il mantenimento degli indici full-text.

Esiste una documentazione Microsoft che menziona il fatto che la deframmentazione dell'indice b-tree della tabella di base e quindi l'esecuzione di una RIORGANIZZAZIONE sul catalogo full-text può migliorare le prestazioni, ma non tocca nessun consiglio più specifico.

Ho anche trovato questa domanda , ma è principalmente focalizzata sul rilevamento delle modifiche (come gli aggiornamenti dei dati alla tabella sottostante vengono propagati nell'indice full-text) e non sul tipo di manutenzione regolarmente programmata che potrebbe massimizzare l'efficienza dell'indice.

Informazioni extra: test delle prestazioni di base

Questo violino SQL contiene codice che può essere utilizzato per creare un indice full-text con AUTOrilevamento delle modifiche ed esaminare sia le dimensioni che le prestazioni della query dell'indice man mano che i dati nella tabella vengono modificati. Quando eseguo la logica dello script su una copia dei miei dati di produzione (al contrario dei dati fabbricati artificialmente nel violino), ecco un riepilogo dei risultati che vedo dopo ogni passaggio di modifica dei dati:

inserisci qui la descrizione dell'immagine

Anche se le dichiarazioni di aggiornamento in questo script sono state abbastanza elaborate, questi dati sembrano mostrare che c'è molto da guadagnare da una manutenzione regolare.

Informazioni extra: idee iniziali

Sto pensando di creare un'attività notturna o settimanale. Sembra che questa attività potrebbe eseguire REBUILD o REORGANIZE.

Poiché gli indici full-text possono essere piuttosto grandi (decine o centinaia di milioni di righe), vorrei essere in grado di rilevare quando gli indici all'interno del catalogo sono sufficientemente frammentati da giustificare un REBUILD / REORGANIZE. Sono un po 'poco chiaro su ciò che l'euristica potrebbe avere senso per questo.

Risposte:


36

Non sono stato in grado di trovare buone risorse online, quindi ho fatto qualche ricerca più pratica e ho pensato che sarebbe stato utile pubblicare il risultante piano di manutenzione full-text che stiamo implementando sulla base di quella ricerca.


La nostra euristica per determinare quando è necessaria la manutenzione

inserisci qui la descrizione dell'immagine

Il nostro obiettivo principale è mantenere prestazioni delle query full-text coerenti con l'evoluzione dei dati nelle tabelle sottostanti. Tuttavia, per vari motivi, sarebbe difficile per noi lanciare una suite rappresentativa di query full-text su ciascuno dei nostri database ogni notte e utilizzare le prestazioni di tali query per determinare quando è necessaria la manutenzione. Pertanto, stavamo cercando di creare regole empiriche che possano essere calcolate molto rapidamente e utilizzate come euristiche per indicare che la manutenzione dell'indice full-text può essere giustificata.

Nel corso di questa esplorazione, abbiamo scoperto che il catalogo di sistema fornisce molte informazioni su come ogni dato indice full-text è diviso in frammenti. Tuttavia, non esiste un "% di frammentazione" ufficiale calcolato (come per gli indici b-tree tramite sys.dm_db_index_physical_stats ). Sulla base delle informazioni sui frammenti full-text, abbiamo deciso di calcolare la nostra "% di frammentazione full-text". Abbiamo quindi utilizzato un server di sviluppo per effettuare ripetutamente aggiornamenti casuali tra 100 e 25.000 righe alla volta su una copia di 10 milioni di righe dei dati di produzione, registrare la frammentazione full-text ed eseguire una query full-text di riferimento utilizzando CONTAINSTABLE.

I risultati, come si vede nei grafici sopra e sotto, sono stati molto illuminanti e hanno mostrato che la misura di frammentazione che avevamo creato è molto correlata alle prestazioni osservate. Dal momento che ciò si lega anche alle nostre osservazioni qualitative nella produzione, è sufficiente che utilizziamo la% di frammentazione come euristica per decidere quando i nostri indici full-text necessitano di manutenzione.

inserisci qui la descrizione dell'immagine


Il piano di manutenzione

Abbiamo deciso di utilizzare il seguente codice per calcolare una% di frammentazione per ogni indice full-text. Eventuali indici full-text di dimensioni non banali con frammentazione di almeno il 10% saranno contrassegnati per essere ricostruiti dalla nostra manutenzione notturna.

-- 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

Queste query producono risultati come i seguenti, e in questo caso le righe 1, 6 e 9 verrebbero contrassegnate come troppo frammentate per prestazioni ottimali poiché l'indice full-text è superiore a 1 MB e frammentato almeno del 10%.

inserisci qui la descrizione dell'immagine


Cadenza di manutenzione

Abbiamo già una finestra di manutenzione notturna e il calcolo della frammentazione è molto economico da calcolare. Quindi eseguiremo questo controllo ogni notte e quindi eseguiremo solo l'operazione più costosa di ricostruzione di un indice full-text quando necessario sulla base della soglia di frammentazione del 10%.


RICOSTRUITO vs. RIORGANIZZARE vs. GOCCIA / CREA

Offerte REBUILDe REORGANIZEopzioni di SQL Server , ma sono disponibili solo per un catalogo full-text (che può contenere un numero qualsiasi di indici full-text) nella sua interezza. Per motivi legacy, abbiamo un unico catalogo full-text che contiene tutti i nostri indici full-text. Pertanto, abbiamo optato per drop ( DROP FULLTEXT INDEX) e quindi ricreare ( CREATE FULLTEXT INDEX) su un singolo livello dell'indice full-text.

Potrebbe essere più ideale suddividere gli indici full-text in cataloghi separati in modo logico ed eseguire un REBUILDinvece, ma nel frattempo la soluzione drop / create funzionerà per noi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.