/*
Automatically reorganizes or rebuilds all partitions in a database
that have an average fragmentation over 10 percent.
IF FRAGMENATION < 30 THEN REORGANIZE INDEX
IF FRAGMENTATION >= 30 THEN REBUILD INDEX
*/
-- Ensure a USE statement has been executed first.
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 @Command nvarchar(4000);
/*Conditionally select tables and indexes from the
sys.dm_db_index_physical_stats function and convert object and index IDs to names*/
SELECT object_id AS ObjectID,index_id AS IndexID,
partition_number AS PartitionNum,
avg_fragmentation_in_percent AS Frag
INTO #work_to_do
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'DETAILED')
WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0 and OBJECT_NAME(OBJECT_ID) like 't_%' ;
select * from #work_to_do
-- 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;
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;
-- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding.
IF @frag < 30.0
SET @command = N'ALTER INDEX ' + @IndexName + N' ON ' + @SchemaName + N'.' + @objectname + N' REORGANIZE';
IF @frag >= 30.0
SET @command = N'ALTER INDEX ' + @IndexName + N' ON ' + @SchemaName + N'.' + @objectname + N' REBUILD';
IF @partitioncount > 1
SET @Command = @Command + N' PARTITION=' + CAST(@PartitionNum AS nvarchar(10));
EXEC (@Command);
PRINT N'Executed: ' + @command;
END;
-- Close and deallocate the cursor.
CLOSE partitions;
DEALLOCATE partitions;
-- Drop the temporary table.
-- DROP TABLE #work_to_do;
No comments:
Post a Comment