Gestire la frammentazione degli indici SQL Database su Azure

di Cristian Civera, in SQL Database,

SQL Database è il servizio di Microsoft Azure che ci permette di usare SQL Server sul cloud. L'ambiente è completamente gestito e configurabile attraverso il portale web. La gestione dei file e dei backup è automatizzata, tanto che a noi non rimane altro che utilizzarlo e scegliere il dimensionamento in termini di spazio massimo e prestazioni.

E' così comodo che finiamo per dimenticarci di alcuni aspetti della manutenzione, in particolare gli indici. Sono praticamente sempre presenti, almeno quelli clustered per le chiavi primarie, e sono sottoposti alla frammentazione che con il passare del tempo si può verificare a causa di continui aggiornamenti, inserimenti e cancellazioni di righe. Questo causa un rallentamento nelle query che ne fanno uso ed è perciò importante tenere monitorata la situazione e se necessario ricostruire gli indici.

Per farlo possiamo usare i comandi SQL. Con lo snippet seguente, per esempio, viene mostrato come visualizzare la frammentazione per ogni indice di ogni tabella, ordinata per la percentuale.

SELECT OBJECT_NAME(ps.object_id) AS TableName
  ,i.name AS IndexName
  ,ips.avg_fragmentation_in_percent
 FROM sys.dm_db_partition_stats ps
 INNER JOIN sys.indexes i ON ps.object_id = i.object_id AND ps.index_id = i.index_id
 CROSS APPLY sys.dm_db_index_physical_stats(DB_ID(), ps.object_id, ps.index_id, null, 'LIMITED') ips
 ORDER BY ips.avg_fragmentation_in_percent DESC

Una volta stabilita quale tabella ricostruire possiamo lanciare il comando ALTER INDEX ALL, oppure ancora lanciare la ricostruzione di tutti gli indici, come nello snippet seguente.

DECLARE @TableName sysname
 
 DECLARE TableCursor CURSOR FOR
 (
 SELECT '[' + IST.TABLE_SCHEMA + '].[' + IST.TABLE_NAME + ']' AS [TableName]
 FROM INFORMATION_SCHEMA.TABLES IST
 WHERE IST.TABLE_TYPE = 'BASE TABLE'
 )
 
 OPEN TableCursor
 FETCH NEXT FROM TableCursor INTO @TableName
 WHILE @@FETCH_STATUS = 0
 
 BEGIN
   PRINT('Rebuilding Indexes on ' + @TableName)
   Begin Try
    EXEC('ALTER INDEX ALL ON ' + @TableName + ' REBUILD with (ONLINE=ON)')
   End Try
   Begin Catch
    PRINT('Cannot do rebuild with Online=On option, taking table ' + @TableName+' down for douing rebuild')
    EXEC('ALTER INDEX ALL ON ' + @TableName + ' REBUILD')
   End Catch
   FETCH NEXT FROM TableCursor INTO @TableName
 END
 
 CLOSE TableCursor
 DEALLOCATE TableCursor

La ricostruzione degli indici può essere fatta online, mantenendoli online e quindi disponibili per le query, ma più lenti nella ricostruzione. Oppure offline, più veloci nella ricostruzione, ma andando ad influire sulle query che ne fanno uso. Questa modalità inoltre è obbligatoria su tabelle che dispongono di colonne di larga dimensione, come NVARCHAR(max). Per questo motivo lo script precedente tenta sempre una ricostruzione online e nel caso non abbia successo, riprova con una offline.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi