Home > SQL > SQL Scripts – Index Defragmentation

SQL Scripts – Index Defragmentation

April 15th, 2010 Leave a comment Go to comments

I have been trying to perfect the art of reorganizing/rebuilding indexes in sql server here lately. I know that this is no where near perfection but is a step beyond the capabilities of SQL Server Management Studio simply because SSMS does not have the ability to take into account the percent of fragmentation. SSMS reorganizes and/or rebuilds every single index regardless of the fragmentation level, which can be a hard hit resource wise. This can also cause a maintenance plan to take several times longer than if the plan had the ability to respond dynamically. So, this is where it begins…..how to dynamically defrag indexes based on the percent of fragmentation. Transact SQL is the only way.

– 1. Reorganizes All Indexes Initially
– 2. Rebuilds Indexes IF Frag Is Not Cleared By Initial Reorganize
– Ignores Indexes <= 5% Fragmented
– Ignores Indexes With Page Count < 100
– Compatible With SQL Server 2005 And Later

IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ‘IndexesToDefrag’) DROP TABLE IndexesToDefrag;

– Round 1 – Reorganize All Indexes With Frag > 5%

SELECT
si.name as IndexName,
OBJECT_NAME(si.object_id) as TableName,
avg_fragmentation_in_percent as Frag
INTO IndexesToDefrag
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, NULL) ips
Join sys.indexes si on ips.object_id = si.object_id
AND ips.index_id = si.index_id
WHERE avg_fragmentation_in_percent > 5
AND index_type_desc <> ‘HEAP’
AND page_count > 100;

DECLARE @Command VARCHAR(100)
DECLARE @Counter INT
DECLARE @IndexName VARCHAR(100)
DECLARE @NumberOfIndexes INT
DECLARE @TableName VARCHAR(100)
DECLARE @Frag INT

SET @NumberOfIndexes = (SELECT COUNT(*) FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, NULL) ips
Join sys.indexes si on ips.object_id = si.object_id
AND ips.index_id = si.index_id
WHERE avg_fragmentation_in_percent > 5
AND index_type_desc <> ‘HEAP’
AND page_count > 100)

SET @Counter = 0

DECLARE DefragCursor CURSOR
FOR SELECT * FROM IndexesToDefrag

OPEN DefragCursor

WHILE @Counter < @NumberOfIndexes
BEGIN
FETCH NEXT FROM DefragCursor INTO @IndexName, @TableName, @Frag
SET @Command = ‘ALTER INDEX ‘ + @IndexName + ‘ ON ‘ + @TableName + ‘ REORGANIZE’ EXEC (@Command) PRINT ‘Executed: ‘ + @command
SET @Counter = @Counter + 1
END

CLOSE DefragCursor
DEALLOCATE DefragCursor

DROP TABLE IndexesToDefrag;

GO

– Round 2 – Rebuild Indexes If Reorganize Was Unsuccessful

SELECT
si.name as IndexName,
OBJECT_NAME(si.object_id) as TableName,
avg_fragmentation_in_percent as Frag
INTO IndexesToDefrag
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, NULL) ips Join sys.indexes si ON ips.object_id = si.object_id AND ips.index_id = si.index_id
WHERE avg_fragmentation_in_percent > 5
AND index_type_desc <> ‘HEAP’
AND page_count > 100;

DECLARE @Command VARCHAR(100)
DECLARE @Counter INT
DECLARE @IndexName VARCHAR(100)
DECLARE @NumberOfIndexes INT
DECLARE @TableName VARCHAR(100)
DECLARE @Frag INT

SET @NumberOfIndexes = (SELECT COUNT(*) FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, NULL) ips
Join sys.indexes si ON ips.object_id = si.object_id
AND ips.index_id = si.index_id
WHERE avg_fragmentation_in_percent > 5
AND index_type_desc <> ‘HEAP’
AND page_count > 100)

SET @Counter = 0

DECLARE DefragCursor CURSOR
FOR SELECT * FROM IndexesToDefrag

OPEN DefragCursor

WHILE @Counter < @NumberOfIndexes
BEGIN
FETCH NEXT FROM DefragCursor INTO @IndexName, @TableName, @Frag
SET @Command = ‘ALTER INDEX ‘ + @IndexName + ‘ ON ‘ + @TableName + ‘ REBUILD’
EXEC (@Command)
PRINT ‘Executed: ‘ + @command
SET @Counter = @Counter + 1
END

CLOSE DefragCursor
DEALLOCATE DefragCursor

DROP TABLE IndexesToDefrag;

  1. Christian Louboutin
    June 12th, 2010 at 02:56 | #1

    Good

  2. forex robot
    July 7th, 2010 at 20:06 | #2

    What a great resource!

  3. Horoskop Panna
    September 9th, 2010 at 22:23 | #3

    Good info

  4. ew
    September 23rd, 2010 at 22:47 | #4

    boom chica wowow

  5. Gavin Sorace
    December 5th, 2010 at 23:44 | #5

    terrible post you admit

  6. Russ Keala
    December 8th, 2010 at 14:00 | #6

    Amazing write-up. Did you study the related piece in the Huffington Publish some time again? It seems that more and more mainstream media are paying attention to this. I hope your website gets more and more subscribers as this problem gets more coverage, because it is a great useful resource.

  7. Joie Seagren
    December 10th, 2010 at 06:24 | #7

    It is always nice to get access to the information posted on this page

  1. No trackbacks yet.
You must be logged in to post a comment.