MSDN Documentation

SQL Server Database Engine

Index Maintenance in SQL Server

Effective index maintenance is crucial for optimal database performance. This section covers strategies and best practices for maintaining indexes in SQL Server to ensure efficient data retrieval and modification.

Why is Index Maintenance Important?

Over time, as data in your tables changes, indexes can become fragmented. This fragmentation can:

Regular maintenance helps to combat these issues by reorganizing or rebuilding indexes.

Types of Index Fragmentation

There are two primary types of index fragmentation:

Index Maintenance Operations

SQL Server provides two main commands for index maintenance:

1. REORGANIZE

The REORGANIZE command defragments the leaf level of an index and reorganizes the pages to be more compact. It's a less resource-intensive operation than REBUILD and can often be performed online (without blocking other operations).

ALTER INDEX index_name ON table_name REORGANIZE;

2. REBUILD

The REBUILD command creates a new, clean copy of the index. This process removes all fragmentation, compacts pages, and can also be used to change index storage options (e.g., partition settings, fill factor). REBUILD is more resource-intensive and can cause significant blocking if not performed carefully, especially on large indexes.

ALTER INDEX index_name ON table_name REBUILD;

Or, to specify options:

ALTER INDEX index_name ON table_name REBUILD WITH (FILLFACTOR = 80, ONLINE = ON);
Tip: Use REORGANIZE for minor fragmentation (typically less than 30% external or internal fragmentation). Use REBUILD for significant fragmentation (greater than 30%).

Determining When to Maintain Indexes

You can query dynamic management views (DMVs) to assess index fragmentation levels:


SELECT
    DB_NAME() AS DatabaseName,
    OBJECT_NAME(ips.object_id) AS TableName,
    i.name AS IndexName,
    ips.index_type_desc,
    ips.avg_fragmentation_in_percent,
    ips.page_count
FROM
    sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') AS ips
JOIN
    sys.indexes AS i ON ips.object_id = i.object_id AND ips.index_id = i.index_id
WHERE
    ips.avg_fragmentation_in_percent > 5 -- Threshold for fragmentation
    AND ips.page_count > 1000 -- Ignore very small indexes
ORDER BY
    ips.avg_fragmentation_in_percent DESC;
            
Important: The fragmentation thresholds (e.g., 5%, 30%) are guidelines. The optimal threshold can vary based on your workload and server resources. Monitor performance to determine the best strategy.

Automating Index Maintenance

Manually maintaining indexes can be time-consuming. Consider implementing an automated solution:

Considerations for Specific Index Types

Best Practices

Note: SQL Server 2017 and later versions have improved online index rebuild capabilities, allowing for more concurrent operations.