禁用索引准则
禁用索引可以防止用户访问索引,而对于聚集索引,则可以防止用户访问基础表数据。SQL Server 2005 数据库引擎 可以在 SQL Server 升级过程中自动禁用索引,您也可以手动禁用索引。有关详细信息,请参阅禁用索引。
可以禁用任何索引类型。禁用索引时,以下规则适用:
- 如果索引是唯一的,将禁用 PRIMARY KEY 约束或 UNIQUE 约束及引用其他表中的索引列的所有 FOREIGN KEY 约束。禁用索引的用户必须对这些表具有 ALTER 权限,否则 ALTER INDEX DISABLE 语句将会失败。如果索引是聚集索引,将禁用基础表的所有传入和传出的 FOREIGN KEY 约束。
索引处于禁用状态时,会在警告消息中列出约束名称。重新生成索引后,必须使用 ALTER TABLE CHECK CONSTRAINT 语句手动启用约束。 - 索引处于禁用状态时,不对其进行维护。
- 查询优化器创建查询执行计划时不考虑索引。另外,引用包含表提示的已禁用索引的查询将失败。
- 不能创建与现有的已禁用索引名称相同的索引,因为该索引定义仍存在于元数据中。
- 可以删除已禁用索引。
禁用非聚集索引
禁用非聚集索引将物理删除索引数据。但索引定义仍保留在元数据中。以下附加准则适用于禁用非聚集索引:
- 有关索引的统计信息保持在原位置,并根据需要自动更新。
- 相关联的聚集索引处于禁用状态时,会自动禁用非聚集索引。表或视图的聚集索引处于启用状态或删除了表的聚集索引时,才能启用这些非聚集索引。除非使用 ALTER INDEX ALL REBUILD 语句启用了聚集索引,否则必须显式启用非聚集索引。有关详细信息,请参阅启用索引和约束指南。
禁用聚集索引
以下附加准则适用于禁用聚集索引:
- 不能访问已禁用的聚集索引的数据行,但可以删除或重新生成该聚集索引。这意味着:
- 会失败的操作有:SELECT、UPDATE、DELETE、INSERT、CREATE INDEX、CREATE STATISTICS、UPDATE STATISTICS(针对索引)和修改表列或约束的 ALTER TABLE 语句。
- 会成功的操作有:CREATE VIEW、DROP VIEW、CREATE TRIGGER、DROP TRIGGER、DROP INDEX、ALTER TABLE ENABLE/DISABLE TRIGGER、TRUNCATE TABLE 和 DROP TABLE。
- 聚集索引处于禁用状态时,不能创建非聚集索引。
- 与表相关的现有非聚集索引和 XML 索引都自动禁用,因此无法访问。
- 引用表的视图的所有聚集索引和非聚集索引都被禁用。必须像重新生成引用表的索引那样重新生成这些索引。
禁用约束
这些附加准则适用于禁用 PRIMARY KEY 约束、FOREIGN KEY 约束和 UNIQUE 约束:
通过使用 ALTER INDEX DISABLE 语句禁用相关联的索引来禁用 PRIMARY KEY 约束和 UNIQUE 约束。
PRIMARY KEY 约束处于禁用状态时,所有相关联的 FOREIGN KEY 约束也将禁用。这相当于对约束设置 NOCHECK CONSTRAINT 选项。
必须对引用表具有 ALTER 权限或 CONTROL 权限。
如果对某个外键引用声明了 CASCADE UPDATE 操作或 DELETE 操作而该引用处于禁用状态,则使约束将修改传播到引用表的任何更新或删除语句都将失败。
PRIMARY KEY 索引或 UNIQUE 索引处于禁用状态,或由于 SQL Server 升级导致索引被禁用,可能有重复的值意外添加到表中。必须先手动更正重复的行,才能成功启用索引。可以使用以下解决方法:
- 手动删除或更改重复的值。
- 如果 UNIQUE 索引并不是因为创建 UNIQUE 约束而创建的,请使用 CREATE INDEX WITH DROP_EXISTING 重新创建索引,但不指定 UNIQUE。
- 如果该索引是因为创建 PRIMARY KEY 约束或 UNIQUE 约束而创建的,则必须删除该约束,该索引也即删除。对于 PRIMARY KEY 约束,还必须删除所有 FOREIGN KEY 约束。
禁用的 FOREIGN KEY 约束和 CHECK 约束均标记为 is_not_trusted。可以在 sys.check_constraints 和 sys.foreign_keys 目录视图中查看这些约束。这意味着系统不再为表的所有行验证约束。即使重新启用约束,系统也不会重新验证表中的现有行,除非指定 ALTER TABLE 的 WITH CHECK 选项。指定 WITH CHECK 后将约束再次标记为受信任。
以下示例中禁用了用于限制数据中所接受薪水的约束。NOCHECK CONSTRAINT 与 ALTER TABLE 一起使用以禁用该约束,从而允许执行通常会违反约束的插入操作。WITH CHECK CHECK CONSTRAINT 重新启用该约束,另外还根据重新启用的约束验证现有数据。CREATE TABLE cnst_example (id INT NOT NULL, name VARCHAR(10) NOT NULL, salary MONEY NOT NULL CONSTRAINT salary_cap CHECK (salary < 100000); ) -- Disable the constraint. ALTER TABLE cnst_example NOCHECK CONSTRAINT salary_cap; -- Reenable the constraint. ALTER TABLE cnst_example WITH CHECK CHECK CONSTRAINT salary_cap;
禁用视图的索引
禁用视图的聚集索引将物理删除索引数据。以下附加准则适用于禁用视图的索引:
- 禁用视图的聚集索引不会妨碍对基础表进行修改。
- 禁用视图的聚集索引也会禁用该视图的所有非聚集索引。
- 聚集索引和非聚集索引的索引数据行均被删除。但视图和索引定义仍保留在元数据中,且可以通过重新生成索引来重新创建。
- ALTER INDEX ALL REBUILD 语句将重新生成并启用表的所有已禁用索引(视图的已禁用索引除外)。视图的索引必须另外使用 ALTER INDEX ALL REBUILD 语句来启用。
- 重新生成视图的聚集索引不会自动启用视图的非聚集索引。
- 在重新生成聚集索引后,必须通过重新生成非聚集索引来手动启用这些非聚集索引。
对已禁用索引执行联机索引操作
表中没有已禁用的聚集索引时,可以联机重新生成已禁用的非聚集索引。但是,如果使用 ALTER INDEX REBUILD 语句或 CREATE INDEX WITH DROP_EXISTING 语句,则务必脱机重新生成已禁用的聚集索引。有关联机索引操作的详细信息,请参阅联机执行索引操作。
有关已禁用索引的统计信息
以下限制适用于索引处于禁用状态时的索引统计信息:
- 无法对包含已禁用的聚集索引的表成功执行 CREATE STATISTICS 语句。
- 当索引处于禁用状态且存在以下条件时,AUTO_CREATE_STATISTICS 数据库选项将对列创建新的统计信息:
- AUTO_CREATE_STATISTICS 设置为 ON
- 当前还没有列的相关统计信息。
- 在查询优化过程中需要统计信息。
- 当指定的表包含已禁用的聚集索引时,sp_autostats 将失败。
- sp_updatestats 不更新有关已禁用的聚集索引的统计信息。
- sp_createstats 创建有关可能是已禁用索引的首要列的统计信息。如果指定了 indexonly,则不对已禁用索引中的列创建统计信息,除非该列还用于其他启用的索引中。
DBCC 命令
如果聚集索引处于禁用状态,DBCC CHECKDB 无法返回有关基础表的信息,而是报告聚集索引处于禁用状态。不能将 DBCC INDEXDEFRAG 用于对已禁用索引进行碎片整理,否则会失败,并显示错误消息。可以使用 DBCC DBREINDEX 重新生成已禁用索引。
查看已禁用索引的状态
当索引或 PRIMARY KEY 约束或 UNIQUE 约束处于禁用状态时,将显示警告消息,其中列出所有受影响的索引以及 FOREIGN KEY 约束或 CHECK 约束。另外,还可以在 sys.indexes 目录视图中或通过使用 INDEXPROPERTY 函数查看索引的禁用状态。可以分别在 sys.foreign_keys 目录视图和 sys.check_constraints 目录视图中查看 FOREIGN KEY 约束和 CHECK 约束的禁用状态。有关详细信息,请参阅查看索引信息。
示例
以下示例禁用了对 Employee
表的非聚集索引。
USE AdventureWorks;
GO
ALTER INDEX IX_Employee_ManagerID
ON HumanResources.Employee DISABLE;
请参阅
概念
其他资源
ALTER INDEX (Transact-SQL)
CREATE INDEX (Transact-SQL)
DBCC CHECKDB (Transact-SQL)
DBCC INDEXDEFRAG (Transact-SQL)
DBCC DBREINDEX (Transact-SQL)
INDEXPROPERTY (Transact-SQL)
sys.check_constraints (Transact-SQL)
sys.foreign_keys (Transact-SQL)
sys.indexes (Transact-SQL)