Stored procedure per ricostruire indici di database frammentati
Una stored procedure riutilizzabile che puoi chiamare per reindicizzare qualsiasi database inserendo il nome del database.
Scopo
Questo è uno stored procedure che puoi letteralmente copiare e incollare nel tuo database Master o Utilities, per reindicizzare tutte le tabelle all'interno di un particolare database.
La parte più utile di questo è che inserisci il nome del database quando chiami la procedura, il che significa che puoi scorrere tutti i tuoi database in una volta chiamando la stessa procedura come segue, se hai server collegati puoi anche chiamarlo da un altro server se chiamato correttamente.
Multiple call SQL
EXEC [Maint].DatabaseReIndex 'ClaytabaseAcademy'
EXEC [Maint].DatabaseReIndex 'YourDatabaseName2'
È stato utile?
Sebbene sia possibile eseguirlo durante l'orario di lavoro, è sempre più sensato eseguirlo quando sul server viene svolto pochissimo lavoro.
SQL
USE [ClaytabaseAcademy]GOBEGIN TRYEXEC sp_executesql N'CREATE SCHEMA Maint'END TRYBEGIN CATCHEND CATCHGOCREATE PROC Maint.DatabaseReIndex(@Database VARCHAR(100)) AS BEGINDECLARE @DbID SMALLINT=DB_ID(@Database)--Get Database IDDECLARE @I TABLE (IndexTempID INT IDENTITY(1,1),SchemaName NVARCHAR(128),TableName NVARCHAR(128),IndexName NVARCHAR(128),IndexFrag FLOAT)INSERT INTO @IEXEC ('USE '+@Database+';SELECT sch.name,OBJECT_NAME(ind.OBJECT_ID) AS TableName,ind.name IndexName,indexstats.avg_fragmentation_in_percentFROM sys.dm_db_index_physical_stats('+@DbID+', NULL, NULL, NULL, NULL) indexstatsINNER JOIN sys.indexes ind ON ind.object_id = indexstats.object_id AND ind.index_id = indexstats.index_idINNER JOIN sys.objects obj on obj.object_id=indexstats.object_idINNER JOIN sys.schemas as sch ON sch.schema_id = obj.schema_idWHERE indexstats.avg_fragmentation_in_percent > 10 AND indexstats.index_type_desc<>''HEAP''ORDER BY indexstats.avg_fragmentation_in_percent DESC')--Get index data and fragmentation, set the percentage as high or low as you needDECLARE @IndexTempID BIGINT=0,@SchemaName NVARCHAR(128),@TableName NVARCHAR(128),@IndexName NVARCHAR(128),@IndexFrag FLOATSELECT * FROM @I--View your results, comment out if not needed...-- Loop through the indexesWHILE @IndexTempID IS NOT NULL BEGIN SELECT @SchemaName=SchemaName,@TableName=TableName,@IndexName=IndexName,@IndexFrag=IndexFrag FROM @I WHERE IndexTempID=@IndexTempID IF @IndexName IS NOT NULL AND @SchemaName IS NOT NULL AND @TableName IS NOT NULL BEGIN IF @IndexFrag<30. BEGIN--Low fragmentation can use re-organise, set at 30 as per most articles PRINT 'USE '+@Database+'; ALTER INDEX ' + @IndexName + N' ON ' + @SchemaName + N'.' + @TableName + N' REORGANIZE' EXEC('USE '+@Database+'; ALTER INDEX ' + @IndexName + N' ON ' + @SchemaName + N'.' + @TableName + N' REORGANIZE') END ELSE BEGIN--High fragmentation needs re-build PRINT 'USE '+@Database+'; ALTER INDEX ' + @IndexName + N' ON ' + @SchemaName + N'.' + @TableName + N' REBUILD' EXEC('USE '+@Database+'; ALTER INDEX ' + @IndexName + N' ON ' + @SchemaName + N'.' + @TableName + N' REBUILD') END END SET @IndexTempID=(SELECT MIN(IndexTempID) FROM @I WHERE IndexTempID>@IndexTempID)ENDENDGO