use Evrim_DB go -- Declare variables: SET NOCOUNT ON DECLARE @tablename VARCHAR(128) DECLARE @execstr VARCHAR(255) DECLARE @objectid INT DECLARE @indexid INT DECLARE @frag decimal DECLARE @maxreorg decimal DECLARE @maxrebuild decimal DECLARE @IdxName varchar(128) DECLARE @pages INT DECLARE @maxpages INT DECLARE @ViewOnly bit DECLARE @ReorgOptions varchar(255) DECLARE @RebuildOptions varchar(255) DECLARE @CreateDate datetime -- Set to 1 to view proposed actions, set to 0 to Execute proposed actions: SET @ViewOnly=0 set @createdate=getdate() -- Decide on the maximum number of pages to consider index for reorg or rebuild: -- NOTE: Set to 0 if you wish not to consider this value for analysis. -- Reference http://sqlblog.com/blogs/kalen_delaney/archive/2008/02/28/fragmentation-revisited.aspx SET @maxpages = 100 -- Decide on the maximum fragmentation to allow for a reorganize: -- AVAILABLE OPTIONS: http://technet.microsoft.com/en-us/library/ms188388(SQL.90).aspx SET @maxreorg = 20.0 SET @ReorgOptions = 'LOB_COMPACTION=ON' -- Decide on the maximum fragmentation to allow for a rebuild: SET @maxrebuild = 30.0 -- NOTE: only specifiy FILLFACTOR=x if x is a value other than 0 (otherwise do not include the fillfactor option at all): SET @RebuildOptions = 'PAD_INDEX=OFF, FILLFACTOR=90, SORT_IN_TEMPDB=ON, STATISTICS_NORECOMPUTE=OFF, ALLOW_ROW_LOCKS=ON, ALLOW_PAGE_LOCKS=ON'
-- Create the temporary table: IF exists (SELECT name FROM tempdb.dbo.sysobjects WHERE name like '#fraglist%') DROP TABLE #fraglist
-- Declare a cursor to process list of tables: DECLARE tables CURSOR FOR SELECT CAST(TABLE_SCHEMA AS VARCHAR(100)) +'.'+CAST(TABLE_NAME AS VARCHAR(100)) AS Table_Name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'
-- Open the cursor: OPEN tables
-- Loop through all the tables in the database: FETCH NEXT FROM tables INTO @tablename WHILE @@FETCH_STATUS = 0 BEGIN -- Perform showcontig on all indexes for the current table: INSERT INTO #fraglist EXEC ('DBCC SHOWCONTIG (''' + @tablename + ''') WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS') declare @hedesi varchar(200)
update #fraglist set ObjectName = @tablename where ObjectName = @hedesi
--truncate table fraglist
FETCH NEXT FROM tables INTO @tablename END
-- Close and deallocate the cursor: CLOSE tables DEALLOCATE tables
-- Declare the cursor for the list of indexes to be defragged: DECLARE indexes CURSOR FOR SELECT ObjectName, ObjectId, IndexId, LogicalFrag, IndexName, CountPages FROM #fraglist --WHERE ((LogicalFrag >= @maxreorg) OR (LogicalFrag >= @maxrebuild)) WHERE INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > 0
-- Open the cursor: OPEN indexes
-- Loop through the indexes: FETCH NEXT FROM indexes INTO @tablename, @objectid, @indexid, @frag, @IdxName, @pages
WHILE @@FETCH_STATUS = 0 BEGIN -- Determine if index page count surpasses the defined threshold for needed maintenance: IF (@pages >= @maxpages) BEGIN -- Determine if fragmentation surpasses the defined threshold for rebuilding: IF (@frag >= @maxrebuild) BEGIN IF (@ViewOnly=1) BEGIN PRINT 'WOULD be executing ALTER INDEX ' + RTRIM(@IdxName) + ' ON ' + RTRIM(@tablename) + ' REBUILD WITH ( ' + @RebuildOptions + ' ) -- Fragmentation currently ' + RTRIM(CONVERT(VARCHAR(15),@frag)) + '% and Pages were ' + RTRIM(CONVERT(VARCHAR(15),@pages)) END ELSE BEGIN PRINT 'Now executing ALTER INDEX ' + RTRIM(@IdxName) + ' ON ' + RTRIM(@tablename) + ' REBUILD WITH ( ' + @RebuildOptions + ' ) -- Fragmentation currently ' + RTRIM(CONVERT(VARCHAR(15),@frag)) + '% and Pages were ' + RTRIM(CONVERT(VARCHAR(15),@pages)) SELECT @execstr = 'ALTER INDEX ' + RTRIM(@IdxName) + ' ON ' + RTRIM(@tablename) + ' REBUILD WITH ( ' + @RebuildOptions + ' )' EXEC (@execstr) END END -- Determine if fragmentation surpasses the defined threshold for reorganizing: ELSE IF (@frag >= @maxreorg) BEGIN IF (@ViewOnly=1) BEGIN PRINT 'WOULD be executing ALTER INDEX ' + RTRIM(@IdxName) + ' ON ' + RTRIM(@tablename) + ' REORGANIZE WITH ( ' + @ReorgOptions + ' ) -- Fragmentation currently ' + RTRIM(CONVERT(VARCHAR(15),@frag)) + '% and Pages were ' + RTRIM(CONVERT(VARCHAR(15),@pages)) END ELSE BEGIN PRINT 'Now executing ALTER INDEX ' + RTRIM(@IdxName) + ' ON ' + RTRIM(@tablename) + ' REORGANIZE WITH ( ' + @ReorgOptions + ' ) -- Fragmentation currently ' + RTRIM(CONVERT(VARCHAR(15),@frag)) + '% and Pages were ' + RTRIM(CONVERT(VARCHAR(15),@pages)) SELECT @execstr = 'ALTER INDEX ' + RTRIM(@IdxName) + ' ON ' + RTRIM(@tablename) + ' REORGANIZE WITH ( ' + @ReorgOptions + ' )' EXEC (@execstr) END END ELSE BEGIN PRINT '--BYPASSING INDEX ' + RTRIM(@IdxName) + ' ON ' + RTRIM(@tablename) + ' since fragmentation is currently ' + RTRIM(CONVERT(VARCHAR(15),@frag)) + '% which is less than the Reorg and Rebuild thresholds.' END END ELSE BEGIN PRINT '--BYPASSING INDEX ' + RTRIM(@IdxName) + ' ON ' + RTRIM(@tablename) + ' since Page Count was ' + RTRIM(CONVERT(VARCHAR(15),@pages)) + ' which is less than threshold. Fragmentation is currently ' + RTRIM(CONVERT(VARCHAR(15),@frag)) + '%' END
FETCH NEXT FROM indexes INTO @tablename, @objectid, @indexid, @frag, @IdxName, @pages END
-- Close and deallocate the cursor: CLOSE indexes DEALLOCATE INDEXES