it-swarm.it

Quando devo ricostruire gli indici?

Quando devo ricostruire gli indici nel mio database relazionale (SQL Server)?

Esiste un caso per ricostruire gli indici su base regolare?

57
Nick Chammas

A rischio di essere troppo generico nella mia risposta, dirò che è necessario eseguire regolarmente un processo di manutenzione dell'indice. Tuttavia, il processo di manutenzione degli indici dovrebbe solo ricostruire/riorganizzare gli indici che lo richiedono specificamente.

Ciò pone la domanda: quando è necessario ricostruire o riorganizzare un indice? Rolando l'ha toccato bene. Ancora una volta, rischio di essere estremamente ampio. Un indice richiede manutenzione quando il livello di frammentazione influisce negativamente sulle prestazioni. Questo livello di frammentazione potrebbe variare in base alla dimensione e alla composizione dell'indice.

Parlando per SQL Server, tendo a scegliere una dimensione dell'indice e un livello di frammentazione dell'indice a quel punto inizio a eseguire la manutenzione dell'indice. Se un indice contiene meno di 100 pagine, non eseguirò alcuna manutenzione.

Se un indice è frammentato tra il 10% e il 30%, io REORGANIZE l'indice e UPDATE le statistiche. Se un indice è frammentato per oltre il 30%, io REBUILD l'indice - senza UPDATE STATISTICS, poiché questo è curato da REBUILD. Ricorda però che una ricostruzione aggiorna solo l'oggetto statistico direttamente associato all'indice. Le altre statistiche sulle colonne dovranno essere gestite separatamente.

Questa risposta è davvero solo una lunga strada da dire: Sì, è necessario eseguire la manutenzione ordinaria degli indici, ma solo sugli indici che ne hanno bisogno.

42
Matt M

Quando devo ricostruire gli indici nel mio database relazionale (ad es. SQL Server)?

Dovresti ricostruire gli indici quando diventano altamente frammentati da eventi speciali. Ad esempio, si esegue un carico di grandi quantità di dati in una tabella indicizzata.

Esiste un caso per ricostruire gli indici su base regolare?

Quindi cosa succede se i tuoi indici vengono frammentati su base regolare a causa di un'attività regolare? Dovresti programmare ricostruzioni regolari? Quanto spesso dovrebbero correre?

Tom Kyte , in questo classico thread Ask Tom , raccomanda:

Il ritardo tra le ricostruzioni dell'indice dovrebbe essere approssimativamente PER SEMPRE.

...

Non so come dirlo meglio: l'indice vuole essere grande e grasso con spazio extra. È su una colonna che aggiorni, spostando la voce dell'indice da un posto all'altro nell'indice. Un giorno la riga ha un codice di "A", il giorno successivo il codice è "G", quindi "Z", quindi "H" e così via. Quindi la voce dell'indice per la riga si sposta da un posto all'altro nell'indice. Mentre lo fa, ha bisogno di spazio - volontà, se lo spazio non è lì, dividiamo il blocco in due - e facciamo spazio. Ora l'indice sta ingrassando. Nel tempo, l'indice ha una dimensione 2-3 volte quella in cui è stato avviato ed è "mezzo o più vuoto", ma va bene dato che si spostano le righe. Ora, quando spostiamo le file, non dobbiamo più dividere i blocchi per fare spazio: la stanza è già disponibile.

Quindi vieni e ricostruisci o rilasci e ricrea l'indice (che hanno gli stessi effetti - solo la ricostruzione è "più sicura") non ha alcuna possibilità di perdere l'indice e può essere più veloce poiché l'indice può essere ricostruito da la scansione dell'indice esistente anziché la scansione della tabella e l'ordinamento e la creazione di un nuovo indice). Ora, tutto quel bello spazio è sparito. Iniziamo il processo di suddivisione dei blocchi da capo, riportandoci al punto di partenza.

Non hai salvato spazio.

L'indice è tornato com'era.

Sprecheresti il ​​tuo tempo per ricostruirlo di nuovo facendo ripetere questo circolo vizioso.

La logica qui è solida, ma è distorta rispetto a un profilo di carico pesante.

Un indice "grasso" (ovvero uno con molti spazi vuoti) in effetti mantiene una buona quantità di spazio per le righe nuove e spostate, riducendo così le divisioni di pagina e mantenendo le tue scritture veloci. Tuttavia, quando leggi da quell'indice fat dovrai leggere più pagine per ottenere gli stessi dati perché ora stai setacciando più spazio vuoto. Questo rallenta le tue letture.

Pertanto, nei database ad alta lettura si desidera ricostruire o riorganizzare regolarmente gli indici. (Con quale frequenza ea quali condizioni? Matt M ha già un risposta concreta a questa domanda.) Nei database che presentano attività di lettura e scrittura approssimativamente equivalenti o in database che sono pesanti in scrittura, è probabile danneggiando le prestazioni del database ricostruendo gli indici regolarmente.

19
Nick Chammas

La maggior parte delle persone li ricostruisce su base regolare in modo da non frammentarsi mai. Quando è necessario ricostruirli, si basa sulla velocità con cui vengono frammentati. Alcuni indici dovranno essere ricostruiti spesso, altri praticamente mai. Dai un'occhiata al script the SQLFool messo insieme che gestisce un sacco di capire queste cose per te.

11
mrdenny

Come osservato nella risposta accettata da Matt M, una regola pratica comune è che gli indici frammentati per oltre il 30% dovrebbero essere ricostruiti.

Questa query ti aiuterà a trovare quanti indici hai oltre il 30% frammentato (quando ne hai alcuni, dovresti ricostruirli):

SELECT DB_NAME() AS DBName,
       OBJECT_NAME(ind.object_id) AS TableName,
       ind.name AS IndexName,
       indexstats.index_type_desc AS IndexType,
       indexstats.avg_fragmentation_in_percent,
       indexstats.fragment_count,
       indexstats.avg_fragment_size_in_pages,
       SUM(p.rows) AS Rows 
  FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) AS indexstats
         INNER JOIN sys.indexes AS ind ON (    ind.object_id = indexstats.object_id
                                           AND ind.index_id = indexstats.index_id)
         INNER JOIN sys.partitions AS p ON (    ind.object_id = p.object_id
                                            AND ind.index_id = p.index_id)
 WHERE indexstats.avg_fragmentation_in_percent > 30
 GROUP BY
       OBJECT_NAME(ind.object_id),
       ind.name,
       indexstats.index_type_desc,
       indexstats.avg_fragmentation_in_percent,
       indexstats.fragment_count,
       indexstats.avg_fragment_size_in_pages 
 ORDER BY indexstats.avg_fragmentation_in_percent DESC
8
amandamaddox3

Quando devo ricostruire gli indici?

Quando la percentuale di frammentazione dell'indice è superiore al 30%.

Esiste un caso per ricostruire gli indici su base regolare?

Non esiste un caso del genere, ma in generale, eseguire la manutenzione dell'indice una volta alla settimana, durante il fine settimana è la migliore pratica per mantenere stabile l'ambiente.

Consiglio di utilizzare gli script di manutenzione di Ola Hallengren (i migliori script di manutenzione), personalizzare gli script in base al proprio ambiente e programmarli per l'esecuzione nel fine settimana.

https://ola.hallengren.com/

Nota: non dimenticare di aggiornare le statistiche dopo aver ricostruito gli indici, poiché la ricostruzione degli indici non aggiorna tutte le statistiche.

5
KrishnaV

Come per la maggior parte delle cose nell'IT, dipende. Quale problema stai cercando di risolvere facendo la ricostruzione degli indici? Puoi mostrare che risolve effettivamente il problema? In tal caso, quindi modificare i numeri fino a trovare la minima quantità di manutenzione che è necessario eseguire per risolvere il problema.

Se non risolve il problema, o il motivo per cui lo stai facendo è solo appagare alcune metriche che controlli perché potrebbero migliorare le cose, allora tutto ciò che stai facendo è bruciare la CPU e IO = e forse peggiorando il tuo problema.

C'è un argomento secondo cui correggere la frammentazione non farà alcuna differenza per il tuo server, quindi vale la pena farlo regolarmente?

https://www.brentozar.com/archive/2017/12/index-maintenance-madness/

http://brentozar.com/go/defrag

1
Greg