SQL to Rebuild Indexes, Update Statistics, and Shrink Databases
Here is SQL to Rebuild Indexes, Update Statistics, and Shrink Databases on SQL Server. This code works on SQL Server 2008 – 2016. It should help keeping your databases running at their peak performance. Just alter the settings as appropriate and away you go! Older legacy SQL2000 kept in for reference.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
--SQL to Rebuild Indexes, Update Statistics, and Shrink Databases on SQL Server --Code from http://cc.davelozinski.com -- This SQL Code will do the following: -- 1) get the names of all the databases on the current SQL server and loop through them -- 2) shrinking each database (if enabled. See <a href="https://msdn.microsoft.com/en-au/library/ms190488.aspx" target="_blank">DBCC SHRINKDATABASE</a>) -- 3) selecting all the tables in the current database -- 4) rebuilding all the indexes on each table (See <a href="https://msdn.microsoft.com/en-AU/library/ms188388.aspx" target="_blank">ALTER INDEX</a>) -- 5) rebuilding all the statistics on each table (See <a href="https://msdn.microsoft.com/en-us/library/ms187348.aspx" target="_blank">UPDATE STATISTICS</a>) -- Adjust the values for the @indexFillFactor, @freeSpaceAfterShrink, @shrinkDatabases as appropriate for your needs. DECLARE @indexFillFactor INT DECLARE @freeSpaceAfterShrink INT DECLARE @shrinkDatabases BIT SET @indexFillFactor = 95 -- the percentage fill factor when rebuilding indexes SET @freeSpaceAfterShrink = 10 -- how much free space to leave after shrinking the database SET @shrinkDatabases = 1 -- 0 = false; 1 = true. ------- nothing below here needs to be configured except maybe the databases to exclude --------------------------------------- DECLARE @Database VARCHAR(255) DECLARE @TableName VARCHAR(512) DECLARE @IndexName VARCHAR(512) DECLARE @IsColumnStoreIndex BIT DECLARE @cmd NVARCHAR(1024) DECLARE DatabaseCursor CURSOR FOR SELECT name FROM [master].[dbo].[sysdatabases] WHERE name NOT IN ('master','msdb','tempdb','model','distribution') ORDER BY 1 OPEN DatabaseCursor FETCH NEXT FROM DatabaseCursor INTO @Database WHILE @@FETCH_STATUS = 0 BEGIN -- shrink the database if you want -------------------------- IF (@shrinkDatabases = 1) BEGIN print 'Shrinking database: ' + @Database DBCC SHRINKDATABASE (@Database, @freeSpaceAfterShrink) END --create the cursor for looping over the indexes by each table SET @cmd = 'DECLARE IndexCursor CURSOR FOR ' + 'SELECT ''['' + table_catalog + ''].['' + table_schema + ''].['' + table_name + '']'' as tableName ' + ',i.name as IndexName ' + ',CASE WHEN i.type_desc like ''%COLUMNSTORE%'' THEN 1 ' + ' ELSE 0 ' + ' END as IsColumnStoreIndex ' + 'FROM [' + @Database + '].[sys].[indexes] i ' + 'INNER JOIN [' + @Database + '].[sys].[all_objects] o on i.object_id = o.object_id ' + 'INNER JOIN [' + @Database + '].[INFORMATION_SCHEMA].[TABLES] t on o.name = t.TABLE_NAME ' + ' AND t.table_type = ''BASE TABLE'' ' + 'INNER JOIN [' + @Database + '].[sys].[schemas] AS s ON o.[schema_id] = s.[schema_id] ' + ' AND SCHEMA_NAME(o.[schema_id]) = t.TABLE_SCHEMA ' + 'ORDER BY o.name' --print (@cmd) EXECUTE sp_executesql @cmd OPEN IndexCursor FETCH NEXT FROM IndexCursor INTO @TableName, @IndexName, @IsColumnStoreIndex WHILE @@FETCH_STATUS = 0 BEGIN --Update indexes -------------------------- -- IF (@@MICROSOFTVERSION / POWER(2, 24) >= 9) --only uncomment these lines if this code used on an SQL2000 database -- BEGIN -- -- SQL 2005 or higher command print 'Started rebuilding Index: [' + @IndexName + '] on table: ' + @TableName + ' at ' + CAST(GetDate() as varchar) IF (@IsColumnStoreIndex = 0) --non columnstore index. Can use FILLFACTOR SET @cmd = 'ALTER INDEX [' + @IndexName + '] ON ' + @TableName + ' REBUILD WITH (FILLFACTOR = ' + CONVERT(VARCHAR(3),@indexFillFactor) + ')' ELSE --ColumnStoreIndex, cannot use FILLFACTOR SET @cmd = 'ALTER INDEX [' + @IndexName + '] ON ' + @TableName + ' REBUILD' --print @cmd EXEC (@cmd) print 'Finished Rebuilding Index: [' + @IndexName + '] on table: ' + @TableName + ' at ' + CAST(GetDate() as varchar) print ' ' -- END -- ELSE -- BEGIN -- -- SQL 2000 command kept just in case -- DBCC DBREINDEX(@Table,' ',@indexFillFactor) -- END FETCH NEXT FROM IndexCursor INTO @TableName, @IndexName, @IsColumnStoreIndex END CLOSE IndexCursor DEALLOCATE IndexCursor -- Update statistics -------------------------- print 'Start updating statistics on DB: ' + @Database + ' at ' + CAST(GetDate() as varchar) SET @cmd = 'USE [' + @Database +']' + CHAR(13) + 'EXEC sp_updatestats' + CHAR(13) --print @cmd EXEC (@cmd) print 'Finished updating statistics on DB: ' + @Database + ' at ' + CAST(GetDate() as varchar) print ' ' FETCH NEXT FROM DatabaseCursor INTO @Database END CLOSE DatabaseCursor DEALLOCATE DatabaseCursor |