How Online Index Operations Work
This topic defines the structures that exist during an online index operation and shows the activities associated with these structures.
To allow for concurrent user activity during an index data definition language (DDL) operation, the following structures are used during the online index operation: source and preexisting indexes, target, and for rebuilding a heap or dropping a clustered index online, a temporary mapping index.
Source and preexisting indexes
The source is the original table or clustered index data. Preexisting indexes are any nonclustered indexes that are associated with the source structure. For example, if the online index operation is rebuilding a clustered index that has four associated nonclustered indexes, the source is the existing clustered index and the preexisting indexes are the nonclustered indexes.
The preexisting indexes are available to concurrent users for select, insert, update, and delete operations. This includes bulk inserts (supported but not recommended) and implicit updates by triggers and referential integrity constraints. All preexisting indexes are available for queries and searches. This means they may be selected by the query optimizer and, if necessary, specified in index hints.
The target or targets is the new index (or heap) or a set of new indexes that is being created or rebuilt. User insert, update, and delete operations to the source are applied by the SQL Server Database Engine to the target during the index operation. For example, if the online index operation is rebuilding a clustered index, the target is the rebuilt clustered index; the Database Engine does not rebuild nonclustered indexes when a clustered index is rebuilt.
The target index is not searched while processing SELECT statements until the index operation is committed. Internally, the index is marked as write-only.
Temporary mapping index
Online index operations that create, drop, or rebuild a clustered index also require a temporary mapping index. This temporary index is used by concurrent transactions to determine which records to delete in the new indexes that are being built when rows in the underlying table are updated or deleted. This nonclustered index is created in the same step as the new clustered index (or heap) and does not require a separate sort operation. Concurrent transactions also maintain the temporary mapping index in all their insert, update, and delete operations.
During a simple online index operation, such as creating a clustered index on a nonindexed table (heap), the source and target go through three phases: preparation, build, and final.
The following illustration shows the process for creating an initial clustered index online. The source object (the heap) has no other indexes. The source and target structure activities are shown for each phase; concurrent user select, insert, update, and delete operations are also shown. The preparation, build, and final phases are indicated together with the lock modes used in each phase.
The following table lists the activities involving the source structures during each phase of the index operation and the corresponding locking strategy.
Very short phase
System metadata preparation to create the new empty index structure.
A snapshot of the table is defined. That is, row versioning is used to provide transaction-level read consistency.
Concurrent user write operations on the source are blocked for a very short period.
No concurrent DDL operations are allowed except creating multiple nonclustered indexes.
S (Shared) on the table*
IS (Intent Shared)
The data is scanned, sorted, merged, and inserted into the target in bulk load operations.
Concurrent user select, insert, update, and delete operations are applied to both the preexisting indexes and any new indexes being built.
Very short phase
All uncommitted update transactions must complete before this phase starts. Depending on the acquired lock, all new user read or write transactions are blocked for a very short period until this phase is completed.
System metadata is updated to replace the source with the target.
The source is dropped if it is required. For example, after rebuilding or dropping a clustered index.
S on the table if creating a nonclustered index.*
SCH-M (Schema Modification) if any source structure (index or table) is dropped.*
* The index operation will wait for any uncommitted update transactions to complete before acquiring the S lock or SCH-M lock on the table.
** The resource lock INDEX_BUILD_INTERNAL_RESOURCE prevents the execution of concurrent data definition language (DDL) operations on the source and preexisting structures while the index operation is in progress. For example, this lock prevents concurrent rebuild of two indexes on the same table. Although this resource lock is associated with the Sch-M lock, it does not prevent data manipulation statements.
The previous table shows a single Shared (S) lock acquired during the build phase of an online index operation that involves a single index. When clustered and nonclustered indexes are built, or rebuilt, in a single online index operation (for example, during the initial clustered index creation on a table that contains one or more nonclustered indexes) two short-term S locks are acquired during the build phase followed by long-term Intent Shared (IS) locks. One S lock is acquired first for the clustered index creation and when creating the clustered index is completed, a second short-term S lock is acquired for creating the nonclustered indexes. After the nonclustered indexes are created, the S lock is downgraded to an IS lock until the final phase of the online index operation.
The following table lists the activities that involve the target structure during each phase of the index operation and the corresponding locking strategy.
New index is created and set to write-only.
Data is inserted from source.
User modifications (inserts, updates, deletes) applied to the source are applied.
This activity is transparent to the user.
Index metadata is updated.
Index is set to read/write status.
The target is not accessed by SELECT statements issued by the user until the index operation is completed.
After the preparation and final phase is completed, the query and update plans that are stored in the procedure cache are invalidated. Subsequent queries will use the new index.
The lifetime of a cursor declared on a table that is involved in an online index operation is limited by the online index phases. Update cursors are invalidated at each phase. Read-only cursors are invalidated only after the final phase.