In SQL Server, we can use the DROP_EXISTING
option of the CREATE INDEX
statement to modify an existing index. It allows us to drop and rebuild an index in one atomic operation. This can be particularly useful when we need to make changes to an index, such as altering its columns, changing its properties, or rebuilding it with different options like fill factor or sort order.
What Can We Do with DROP_EXISTING
?
We can use DROP_EXISTING
to modify an index by automatically dropping it and recreating it with the new definition. This is done in the CREATE INDEX
statement, and so it saves us from having to use a separate DROP INDEX
statement before the CREATE INDEX
statement.
In particular, we can:
- Rebuild the index
- Add or drop columns
- Modify options
- Modify column sort order
- Change the partition scheme or filegroup.
Example
Here’s an example that demonstrates how to use the DROP_EXISTING
option in SQL Server. First we’ll create a table and add an index to it. Then we’ll update the index using CREATE INDEX
with the DROP_EXISTING
option.
1. Create a Sample Table and Index
First, let’s create the initial table and index:
-- Create a sample table
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
FirstName NVARCHAR(50),
LastName NVARCHAR(50),
DepartmentID INT
);
-- Create a non-clustered index on the LastName column
CREATE INDEX IX_Employees_Name
ON Employees (LastName);
2. Modify the Index Using DROP_EXISTING
Now suppose we want to include the FirstName
column in the index to improve the performance of queries that filter on both LastName
and FirstName
. We can use the DROP_EXISTING
option to achieve this without needing to manually drop the index first:
-- Modify the existing index to include the FirstName column
CREATE INDEX IX_Employees_Name
ON Employees (LastName, FirstName)
WITH (DROP_EXISTING = ON);
This script drops the existing IX_Employees_Name
index and recreates it with the additional column FirstName
. All done in an atomic operation.
Alternative Syntax
There are a couple of ways we can use DROP_EXISTING
. We can use either of the following:
WITH (DROP_EXISTING = ON);
WITH DROP_EXISTING;
- The first method is more explicit. It’s where we explicitly set it to
ON
. Note that this requires parentheses around theDROP_EXISTING = ON
part. - The second method is more concise. Simply by stating
DROP_EXISTING
, this is enough to turn it on. This is actually the backward compatible syntax.
Can and Cannots
Microsoft points out that there are certain things we can and can’t do with DROP_EXISTING
:
We can change:
- A nonclustered rowstore index to a clustered rowstore index.
We can’t change:
- A clustered rowstore index to a nonclustered rowstore index.
- A clustered columnstore index to any type of rowstore index.
Also, the Microsoft documentation has some important information around how DROP_EXISTING
works in various contexts.
Benefits of DROP_EXISTING
The DROP_EXISTING
option provides some decent benefits over dropping and recreating the index manually. Here are some of them:
- Efficiency:
DROP_EXISTING
is generally more efficient than dropping/recreating the index manually because it performs the drop and create in a single operation, avoiding the overhead of two separate operations. - Atomic Operation: Using
DROP_EXISTING
ensures that the index is dropped and recreated in a single transaction. This atomicity means that if anything goes wrong during the process, the database will not be left in an inconsistent state. - Reduced Locking and Blocking: Rebuilding the index in one step can reduce the time locks are held on the table, potentially minimizing blocking compared to manually dropping and recreating the index.
- Indexed Views and Clustered Indexes: If you’re dealing with a clustered index or an index on an indexed view, the
DROP_EXISTING
option is especially useful because dropping a clustered index would drop all associated non-clustered indexes. WithDROP_EXISTING
, these are rebuilt automatically. - Ease of Use: The
DROP_EXISTING
option simplifies the process of recreating the index, reducing the chance of errors (e.g., forgetting to recreate the index or mistyping the index name).
When to Use DROP_EXISTING
Here are some scenarios where the DROP_EXISTING
option can come in handy:
- Index Modification: When you need to change the columns included in the index or modify its options like fill factor, compression, or sort order.
- Rebuilding After Maintenance: When rebuilding an index with changes, like after altering the underlying table structure.
- Performance Optimization: When optimizing indexes, such as adding included columns or changing the index structure to better support queries.
- Indexed Views: When you need to modify the clustered index on an indexed view, ensuring that dependent non-clustered indexes are automatically handled.
Example of When Not to Use DROP_EXISTING
Just because DROP_EXISTING
is an amazing option, it doesn’t mean it can be used all the time. Here are some occasions where you wouldn’t want to use it:
- Completely New Index: If you’re creating a new index that does not already exist, there’s no need for
DROP_EXISTING
(and it will result in an error instead). - Unnecessary Rebuilds: If the index does not need to be modified, dropping and recreating it might incur unnecessary overhead.
Conclusion
SQL Server’s DROP_EXISTING
option is a handy feature for managing indexes efficiently. It ensures that index modifications are done atomically, preserves index statistics, and reduces the potential for errors or inconsistencies. This option should be used whenever you need to modify an existing index without incurring the overhead and risks associated with manually dropping and recreating it.