聚集与非聚集索引

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例

索引是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度。 索引包含由表或视图中的一列或多列生成的键。 这些键存储在一个结构(B 树)中,使 SQL Server 可以快速高效地找到与键值关联的行。

注意

SQL Server 文档在提到索引时一般使用 B 树这个术语。 在行存储索引中,SQL Server 实现了 B+ 树。 这不适用于列存储索引或内存中数据存储。 有关详细信息,请参阅 SQL Server 以及 Azure SQL 索引体系结构和设计指南

表或视图可以包含以下类型的索引:

  • 群集

    • 聚集索引根据数据行的键值在表或视图中排序和存储这些数据行。 这些键值是索引定义中包含的列。 每个表只能有一个聚集索引,因为数据行本身只能按一个顺序存储。  
    • 只有当表包含聚集索引时,表中的数据行才按排序顺序存储。 如果表具有聚集索引,则该表称为聚集表。 如果表没有聚集索引,则其数据行存储在一个称为堆的无序结构中。
  • 非聚集

    • 非聚集索引具有独立于数据行的结构。 非聚集索引包含非聚集索引键值,并且每个键值项都有指向包含该键值的数据行的指针。

    • 从非聚集索引中的索引行指向数据行的指针称为行定位器。 行定位器的结构取决于数据页是存储在堆中还是聚集表中。 对于堆,行定位器是指向行的指针。 对于聚集表,行定位器是聚集索引键。

    • 可以向非聚集索引的叶级添加非键列以跳过现有的索引键限制,并执行完整范围内的索引查询。 有关详细信息,请参阅创建带有包含列的索引。 有关索引键限制的详细信息,请参阅 SQL Server 的最大容量规范

聚集索引和非聚集索引都可以是唯一的。 使用唯一索引后,任何两行都不能有相同的索引键值。 否则,索引不是唯一的,即多行可以共享同一键值。 有关详细信息,请参阅创建唯一索引

每当修改了表数据后,都会自动维护表或视图的索引。

有关更多类型的特殊用途索引,请参阅索引

索引和约束

对表列定义了 PRIMARY KEY 约束和 UNIQUE 约束时,SQL Server 会自动创建索引。 例如,在创建带 UNIQUE 约束的表时,数据库引擎自动创建非聚集索引。 如果你配置 PRIMARY KEY,数据库引擎会自动创建聚集索引(除非聚集索引已存在)。 如果你尝试对现有表强制执行 PRIMARY KEY 约束,且此表上已有聚集索引,SQL Server 使用非聚集索引强制执行主键。

有关详细信息,请参阅创建主键创建唯一约束

查询优化器如何使用索引

设计良好的索引可以减少磁盘 I/O 操作,并且消耗的系统资源也较少。 因此,这些索引可提高查询性能。 对于包含 SELECT、UPDATE、DELETE 或 MERGE 语句的各种查询,索引会很有用。 例如,在 SELECT JobTitle, HireDate FROM HumanResources.Employee WHERE BusinessEntityID = 250 数据库中执行的查询 AdventureWorks2022 。 执行此查询时,查询优化器评估可用于检索数据的每个方法,然后选择最有效的方法。 可能采用的方法包括扫描表和扫描一个或多个索引(如果有)。

扫描表时,查询优化器读取表中的所有行,并提取满足查询条件的行。 扫描表会有许多磁盘 I/O 操作,并占用大量资源。 但是,如果查询的结果集是占表中较高百分比的行,扫描表会是最为有效的方法。

查询优化器使用索引时,搜索索引键列,查找到查询所需行的存储位置,然后从该位置提取匹配行。 通常,搜索索引的速度比搜索表快得多。 与表不同,索引通常每行包含很少的列,行按排序顺序排列。

查询优化器在执行查询时通常会选择最有效的方法。 但如果没有索引,则查询优化器必须扫描表。 您的任务是设计并创建最适合您的环境的索引,以便查询优化器可以从多个有效的索引中选择。 SQL Server 提供数据库引擎优化顾问以帮助分析数据库环境并选择适当的索引。

重要

要深入了解索引设计指南和内部机制,请参阅《SQL Server 和 Azure SQL 索引体系结构和设计指南》。

后续步骤