Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically Drop and Recreate current indexes

I'm working on providing a method to allow for bulk updating our tables ( greater than 1M new or updated rows per update) and was interested in dropping the current indexes and recreating them after the updates.

I was wondering if anyone has a script to provide loose coupling of these operations so that if the indexes change over time, the update process does not change.

It seems like this is one of those things that the community has already probably solved.

like image 253
Marty Trenouth Avatar asked Jul 02 '12 21:07

Marty Trenouth


People also ask

How do I drop and recreate an index?

There is no direct way to DROP and recreate indexes. You can script all required indexes before dropping. Once you have changed data types you can use those CREATE scripts to recreate indexes.

Which index process drops the existing index and recreate the index?

Rebuilding an index drops and re-creates the index. This removes fragmentation, reclaims disk space by compacting the pages based on the specified or existing fill factor setting, and reorders the index rows in contiguous pages.

How do I automate an index rebuild in SQL Server?

The option is under the Management node of SQL Server management studio. Right-click on Maintenance Plans and select New Maintenance Plan… Provide the appropriate name of the maintenance plan. Drag and drop the index rebuild task from the maintenance plan toolbox.

Does Azure automatically rebuild indexes?

Azure does not support rebuilding indexes using SQL Server Management Studio. It also does not support maintenance plans and does not use a SQL Server Agent. Therefore, a manual approach to rebuilding indexes is required.


2 Answers

I have script that I use to query the system tables to capture all non-clustered indexes and disable then rebuild upon completion. The below is for use on standard edition, if you are on enterprise I would add the ONLINE option.

Disable

DECLARE @sql AS VARCHAR(MAX);
SET @sql = '';
SELECT 
    @sql = @sql + 'ALTER INDEX [' + i.name + '] ON [' + o.name + '] DISABLE; '
FROM sys.indexes AS i
JOIN sys.objects AS o ON i.object_id = o.object_id
WHERE i.type_desc = 'NONCLUSTERED'
AND o.type_desc = 'USER_TABLE'

EXEC (@sql)

Rebuild

DECLARE @sql AS VARCHAR(MAX);
SET @sql = '';
SELECT 
    @sql = @sql + 'ALTER INDEX [' + i.name + '] ON [' + o.name + '] REBUILD WITH (FILLFACTOR = 80); '
FROM sys.indexes AS i
JOIN sys.objects AS o ON i.object_id = o.object_id
WHERE i.type_desc = 'NONCLUSTERED'
AND o.type_desc = 'USER_TABLE'

EXEC (@sql);

I like this method as it is very customizable as you can exclude/include certain tables based on the conditions as well as avoiding a cursor. Also you can change the EXEC to a PRINT and see the code that will execute and manually run it.

Condition to exclude a table

AND o.name NOT IN ('tblTest','tblTest1');
like image 50
Dustin Laine Avatar answered Oct 22 '22 18:10

Dustin Laine


EXEC sp_MSforEachTable 'ALTER INDEX ALL ON ? DISABLE'

and

EXEC sp_MSforEachTable 'ALTER INDEX ALL ON ? REBUILD'

is all you need if you want to do it for all tables and every index.

like image 4
fancyPants Avatar answered Oct 22 '22 20:10

fancyPants