Pagine

sabato 14 settembre 2013

Script Rebuild o Reoganize ?

E' sempre necessario fare la rebuild di un indice o posso farne la reorganize ?
Per dirla in modo estrememente sintetico e semplificato, la Rebuild è molto efficiente  ma pesante , la Reorganize meno efficace ma più leggera...
La prima è utile quando è necessario ricostruire la struttura al fine di ripristinare il livello di performance adeguato, la seconda è utile quando la struttura non è molto frammentata e le performance sono ancora accettabili.

Qui trovate un articolo dettagliato su come determinare la frammentazione di un indice e come intervenire.

Lo script, trasformabile in stored procedure fa riferimento a :
  1. @Pages_Limits = numero minimo di datapages che compone l'indice. se l'indice è composto da un numero di data pages inferiore non viene preso in considerazione.
  2. @Fragmentation_Limits = % di frammentazione sotto la quale viene eseguita la Reorganize. Se la percentuale di frammentazione dell'indice è superiore al valore della variabile viene eseguita la Rebuild.

DECLARE @Pages_Limits INT = 1500
DECLARE @Fragmentation_Limits TINYINT = 30
DECLARE @StrCmd VARCHAR(max) = ''

SELECT @StrCmd = @StrCmd +
 'ALTER INDEX ' + QUOTENAME(I.name) + ' ON ' + QUOTENAME(S.name) + '.' + QUOTENAME(O.name) 
 + IIF(F.avg_fragmentation_in_percent > 10 AND F.avg_fragmentation_in_percent < @Fragmentation_Limits,' REORGANIZE',' REBUILD')
 + IIF(ISNULL(P.[Partitions],0) > 1,' PARTITION = ' + CAST(F.partition_number AS VARCHAR(5)),'')+ Char(13)
FROM sys.dm_db_index_physical_stats(DB_ID() , NULL, NULL , NULL , 'LIMITED') F
 LEFT JOIN 
        (
     SELECT Object_id
     ,index_id
     ,Count(*) [Partitions]  
     FROM sys.partitions
      GROUP BY Object_id,index_id
        ) P ON F.object_id = P.object_id and F.index_id = P.index_id
 INNER JOIN sys.indexes I
  ON F.object_id = I.object_id and F.index_id = I.index_id
 INNER JOIN sys.all_objects O
  ON F.object_id = O.object_id
 INNER JOIN sys.schemas S
  ON O.schema_id = S.schema_id
WHERE I.type != 0 and F.page_count >= @Pages_Limits
ORDER BY page_count DESC

PRINT(@StrCmd)

Lo script genera il comando di ALTER INDEX per tutte le strutture coinvolte
(Nell'esempio è modificato per monitorare una tabella specifica chiamata SlowQueries")















Se si desidera eseguirlo senza preview basta aggiungere il comando di EXEC(@StrCmd)

N.B.1.
Eseguire Rebuild in ambiente di produzione può impedire l'uso della tabella/indice su cui si sta eseguendo l'operazione con ripercussioni su tutte le connessioni e le attività che tentano di accedervi !!!!!! Da fare con molta cautela !!!

N.B.2. Lo script è per SQL Server 2012.
Per renderlo compatibile con SQL Server 2005,2008,2008R2 è necessario convertire l'operatore ternario IIF in CASE WHEN.

Ciao

Luca

Nessun commento:

Posta un commento