Je mehr sich in der betroffenen Tabelle ändert, desto höher wird die Fragmentierung. Dies wirkt sich natürlich auch auf die Durchführungszeit von unzähligen Queries aus.
Daher ist es ratsam regelmäßig die Indizes zu reorganisieren oder überhaupt neu aufzubauen.
Dies ist mit dem unten angeführten Skript einfach realisierbar.
Mit der derzeitigen Einstellungen, werden alle Indizes, welche eine Fragmentierung über 10% aufweisen neu aufgebaut (rebuild oder reorg). Der Index Neuaufbau verbraucht mehr CPU, als ein Index-Reorg. In meinem konkreten Fall ist dies vernachlässigbar, da eine Beladung nur einmal täglich durchgeführt wird und danach auf diesem Beladeserver nicht viel los ist.
Empfehlung:
Es gibt viele Einstellungsmöglichkeiten, jeder sollte ausprobieren, welche für seinen konkreten Fall, die ideale Lösung darstellt.
Grundsätzlich sollten Indizes, welche eine Fragmentierung über 30% aufweisen, mit einem REBUILD und Indizes mit einer Framentierung zwischen 10% und 30% mit einem REORG bereinigt werden.
Zusätzlich gibt es in der SQL Server Development Version und Enterprise Version die ONLINE-Option. Durch diese bleibt der Fragmentierte Index während der REBUILD-Phase weiterhin verfügbar.
/* Dieses Skript überprüft in der angegebenen Datenbank alle Indizes bezüglich Fragmentierung. Ist der Index zu fragmentiert - Schwellwert in % überschritten - wird ein Rebuild auf ebendiesen abgesetzt. */ USE MyDatabase -- $$change - Hier den Datenbanknamen einfügen GO BEGIN TRY BEGIN TRAN SET NOCOUNT ON; DECLARE @objectid int; DECLARE @indexid int; DECLARE @partitioncount bigint; DECLARE @schemaname nvarchar(130); DECLARE @objectname nvarchar(130); DECLARE @indexname nvarchar(130); DECLARE @partitionnum bigint; DECLARE @partitions bigint; DECLARE @frag float; DECLARE @pagecount int; DECLARE @command nvarchar(4000); DECLARE @page_count_minimum smallint SET @page_count_minimum = 500 -- $$change - Hier Mindestwert für Pageanzahl der zu prüfenden Indizes angeben DECLARE @fragmentation_minimum float SET @fragmentation_minimum = 10.0 -- $$change - Hier den Schwellwert der Fragmentierung in Prozent angeben SELECT object_id AS objectid, index_id AS indexid, partition_number AS partitionnum, avg_fragmentation_in_percent AS frag, page_count AS page_count INTO #work_to_do FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED') WHERE avg_fragmentation_in_percent > @fragmentation_minimum AND index_id > 0 AND page_count > @page_count_minimum; -- Declare the cursor for the list of partitions to be processed. DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do; -- Open the cursor. OPEN partitions; -- Loop through the partitions. WHILE (1=1) BEGIN; FETCH NEXT FROM partitions INTO @objectid, @indexid, @partitionnum, @frag, @pagecount; IF @@FETCH_STATUS < 0 BREAK; SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name) FROM sys.objects AS o JOIN sys.schemas as s ON s.schema_id = o.schema_id WHERE o.object_id = @objectid; SELECT @indexname = QUOTENAME(name) FROM sys.indexes WHERE object_id = @objectid AND index_id = @indexid; SELECT @partitioncount = count (*) FROM sys.partitions WHERE object_id = @objectid AND index_id = @indexid; SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname;
IF @frag > 30 SET @command = @command + + N' REBUILD'; ELSE IF @frag <= 30 SET @command = @command + + N' REORG';
IF @partitioncount > 1 SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS nvarchar(10)); PRINT @command EXEC (@command); IF @frag > 30 PRINT N'Rebuilding index ' + @indexname + ' on table ' + @objectname; ELSE IF @frag <= 30 PRINT N'Reorganizing index ' + @indexname + ' on table ' + @objectname; PRINT N' Fragmentation: ' + CAST(@frag AS varchar(15)); PRINT N' Page Count: ' + CAST(@pagecount AS varchar(15)); PRINT N' '; END; -- Close and deallocate the cursor. CLOSE partitions; DEALLOCATE partitions; -- Drop the temporary table. DROP TABLE #work_to_do; COMMIT TRAN END TRY BEGIN CATCH ROLLBACK TRAN PRINT 'ERROR ENCOUNTERED' END CATCH
Keine Kommentare:
Kommentar veröffentlichen