T-SQL Script: Automatic Index Maintenance Script
T-SQL Script: Automatic Index Maintenance Script (Reorganize or Rebuild depending on Index fragmentation )
SET NOCOUNT ON;
DECLARE
@object_id INT,
@index_id INT,
@schema_name SYSNAME,
@table_name SYSNAME,
@index_name SYSNAME,
@frag FLOAT,
@sql NVARCHAR(MAX);
-- Cursor over fragmented indexes
DECLARE cur CURSOR FOR
SELECT
ips.object_id,
ips.index_id,
ips.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') ips
JOIN sys.indexes i
ON ips.object_id = i.object_id
AND ips.index_id = i.index_id
WHERE
i.index_id > 0 -- ignore heaps
AND ips.avg_fragmentation_in_percent > 5; -- only process meaningful fragmentation
OPEN cur;
FETCH NEXT FROM cur INTO @object_id, @index_id, @frag;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
@schema_name = s.name,
@table_name = t.name,
@index_name = i.name
FROM sys.objects t
JOIN sys.schemas s ON t.schema_id = s.schema_id
JOIN sys.indexes i ON t.object_id = i.object_id AND i.index_id = @index_id
WHERE t.object_id = @object_id;
IF @frag BETWEEN 5 AND 30
BEGIN
SET @sql =
'ALTER INDEX [' + @index_name + '] ON [' + @schema_name + '].[' + @table_name + '] REORGANIZE;';
PRINT 'Reorganizing: ' + @schema_name + '.' + @table_name + ' (' + @index_name + ') — Fragmentation: ' + CAST(@frag AS VARCHAR(10));
END
ELSE IF @frag > 30
BEGIN
SET @sql =
'ALTER INDEX [' + @index_name + '] ON [' + @schema_name + '].[' + @table_name + '] REBUILD;';
PRINT 'Rebuilding: ' + @schema_name + '.' + @table_name + ' (' + @index_name + ') — Fragmentation: ' + CAST(@frag AS VARCHAR(10));
END
EXEC(@sql);
FETCH NEXT FROM cur INTO @object_id, @index_id, @frag;
END
CLOSE cur;
DEALLOCATE cur;
PRINT 'Index maintenance completed.';
DECLARE
@object_id INT,
@index_id INT,
@schema_name SYSNAME,
@table_name SYSNAME,
@index_name SYSNAME,
@frag FLOAT,
@sql NVARCHAR(MAX);
-- Cursor over fragmented indexes
DECLARE cur CURSOR FOR
SELECT
ips.object_id,
ips.index_id,
ips.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') ips
JOIN sys.indexes i
ON ips.object_id = i.object_id
AND ips.index_id = i.index_id
WHERE
i.index_id > 0 -- ignore heaps
AND ips.avg_fragmentation_in_percent > 5; -- only process meaningful fragmentation
OPEN cur;
FETCH NEXT FROM cur INTO @object_id, @index_id, @frag;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
@schema_name = s.name,
@table_name = t.name,
@index_name = i.name
FROM sys.objects t
JOIN sys.schemas s ON t.schema_id = s.schema_id
JOIN sys.indexes i ON t.object_id = i.object_id AND i.index_id = @index_id
WHERE t.object_id = @object_id;
IF @frag BETWEEN 5 AND 30
BEGIN
SET @sql =
'ALTER INDEX [' + @index_name + '] ON [' + @schema_name + '].[' + @table_name + '] REORGANIZE;';
PRINT 'Reorganizing: ' + @schema_name + '.' + @table_name + ' (' + @index_name + ') — Fragmentation: ' + CAST(@frag AS VARCHAR(10));
END
ELSE IF @frag > 30
BEGIN
SET @sql =
'ALTER INDEX [' + @index_name + '] ON [' + @schema_name + '].[' + @table_name + '] REBUILD;';
PRINT 'Rebuilding: ' + @schema_name + '.' + @table_name + ' (' + @index_name + ') — Fragmentation: ' + CAST(@frag AS VARCHAR(10));
END
EXEC(@sql);
FETCH NEXT FROM cur INTO @object_id, @index_id, @frag;
END
CLOSE cur;
DEALLOCATE cur;
PRINT 'Index maintenance completed.';