Efficiently Rebuild SQL Server Clustered Indexes with DROP_EXISTING


By:   |   Updated: 2007-10-30   |   Comments (2)   |   Related: 1 | 2 | 3 | 4 | 5 | 6 | More > Fragmentation and Index Maintenance

Problem

When re-building a table's clustered index using a DROP INDEX command followed by a CREATE INDEX command, if a table has non-clustered indexes then all of non-clustered indexes on the table may be automatically rebuilt twice by the SQL Server engine.  Once when the clustered index is dropped and a second time when the index is created again, depending on the new clustered index definition. Is there some way we can eliminate the system resource overhead of rebuilding all of the table's non-clustered indexes twice?

Solution

To efficiently rebuild a clustered index, the CREATE INDEX command provides the DROP_EXISTING option. This option can rebuild the clustered index in a single atomic step and re-creates the non-clustered indexes of the table only once depending on the index definition.  This sets each index leaf level page pointer to the clustered index key while eliminating the overhead of setting the index page leaf pointer to a direct address first. On very large tables, the resource savings can be immense.

As a point of reference, each index leaf level page of a non-clustered index contains a pointer to where the data requested resides. This pointer can be one of two values. For tables without a clustered index, this pointer is a direct address to a data page. For tables with a clustered index, this value is a pointer to the clustered index key related to the data.  When a table's clustered index is dropped using a DROP command and then re-added using a CREATE command, each non-clustered index on the table can be re-created twice. When the DROP is initiated, all non-clustered indexes on the table are re-created to reset its index page pointers to directly address a data page. When the CREATE is then executed, the non-clustered indexes are re-created again, this time with a pointer set back to a clustered index key.

As is the case with many features related to SQL Server 2005, they have been enhanced over the SQL Server 2000 functionality.  Let's dive into some of the small details related to the DROP_EXISTING option of the CREATE INDEX command between SQL Server 2000 and 2005:

The DROP_EXISTING option can also be used in the following scenarios:
SQL Server 2000 SQL Server 2005
  • Rebuild a preexisting clustered index
  • Rebuild a preexisting non-clustered index
  • Rebuild a non-clustered index as a clustered index if a clustered index is not already defined
  • Rebuild an index and add or remove the keys
  • Rebuild an index to add or remove uniqueness
  • Rebuild a preexisting clustered index
  • Rebuild a preexisting non-clustered index
  • Rebuild a non-clustered index as a clustered index if a clustered index is not already defined
  • Rebuild an index and add or remove the keys
  • Rebuild an index to add or remove uniqueness
  • Rebuild an index to modify options
  • Rebuild an index to modify sort order
  • Rebuild an index to modify the partition scheme or filegroup
  • If an index enforces a PRIMARY KEY or UNIQUE constraint and the definition is not alerted, then the index can be dropped and re-created
  • If the index definition has the same name, key and partition columns, uniqueness attributes and sort order, then the non-clustered indexes are not rebuilt
Limitations to using DROP_EXISTING option:
SQL Server 2000 SQL Server 2005
  • The index must already exist; using this option will not allow creation of an index from scratch
  • You cannot use it to rebuild a clustered index to be non-clustered
  • If rebuilding an index tied to a constraint, you cannot change the index's definition
  • The index must already exist; using this option will not allow creation of an index from scratch
  • You cannot use it to rebuild a clustered index to be non-clustered
  • If rebuilding an index tied to a constraint, you cannot change the index's definition
  • The non-clustered indexes will always remain in the original file group or partition scheme with the original partition functions even if the clustered index is rebuilt to another file group or partition
  • If an index enforces a PRIMARY KEY or UNIQUE constraint and the definition is alerted, then drop the constraint and add the constraint with the new definition

Here is an example of the DROP_EXISTING option of the CREATE INDEX command in action:

Sample DROP_EXISTING Code
SQL Server 2000 SQL Server 2005
CREATE CLUSTERED INDEX au_id_clidx
ON Authors (au_id)
WITH DROP_EXISTING
GO
CREATE CLUSTERED INDEX au_id_clidx
ON dbo.Authors (au_id)
WITH (DROP_EXISTING = ON);
GO
Next Steps

 



Last Updated: 2007-10-30


get scripts

next tip button



About the author




Post a comment or let the author know this tip helped.

All comments are reviewed, so stay on subject or we may delete your comment. Note: your email address is not published. Required fields are marked with an asterisk (*).

*Name
*Email
Email me updates

Signup for our newsletter

I agree by submitting my data to receive communications, account updates and/or special offers about SQL Server from MSSQLTips and/or its Sponsors. I have read the privacy statement and understand I may unsubscribe at any time.





Friday, October 25, 2019 - 9:58:09 PM - Jeff Moden Back To Top

To answer the old question posed by Mushtaq back on March 21, 2013, which basically asked how to "create a Primary Key Clustered Iwith DROP EXISTING" (and is a great question), please refer to the following Microsoft Documentation link...

https://docs.microsoft.com/en-us/sql/t-sql/statements/create-index-transact-sql?view=sql-server-ver15

Remember first that contraints like Primary Keys always cause an index to materialize to enforce the constraint.  Then, check the link I posted and find where it states...

"If the index enforces a PRIMARY KEY or UNIQUE constraint and the index definition is not altered in any way, the index is dropped and re-created preserving the existing constraint."

In plain English, you can't create a new Primary Key constraint using CREATE INDEX and that means that you can't use WITH DROP EXISTING when you create a constraint like a Primary Key.  You CAN, however, drop and rebuild the index that supports such a constraint with CREATE INDEX WITH DROP EXISTING (remember that a PK is unique and cannot be null and the index must be recreated just like that).

Also be aware that you cannot actually redefine an index that enforces a constraint.  You must first drop the constraint and then rebuild the constraint.  That's also documented in the same paragraph in the article.


Thursday, March 21, 2013 - 11:20:56 AM - Mushtaq Back To Top

Hello, great article and i have one Question.

 

As you mentioned, the drop_existing can be used for : If an index enforces a PRIMARY KEY or UNIQUE constraint and the definition is not alerted, then the index can be dropped and re-created. I wonder what would be the syntax to 'Create a primary key clustered index WITH DROP_EXISTING'

As we have to you Alter table to add or remove primarky key and Drop_existing cannot be used with Alter table. How can i use Drop_existing when primary key is involved.

 

Thank you

Mushtaq.



download

























get free sql tips

I agree by submitting my data to receive communications, account updates and/or special offers about SQL Server from MSSQLTips and/or its Sponsors. I have read the privacy statement and understand I may unsubscribe at any time.



Learn more about SQL Server tools