SQL Server 聚集索引 clustered index 非聚集索引Nonclustered Indexes键查找查找Key Lookup执行计划过程详解

Posted ShenLiang2025

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL Server 聚集索引 clustered index 非聚集索引Nonclustered Indexes键查找查找Key Lookup执行计划过程详解相关的知识,希望对你有一定的参考价值。

SQL Server 聚集索引非聚集索引键查找过程详解

索引的相关术语

1 堆(Heap)是一种没有指定排序的数据结构,通俗的理解堆就像是按照顺序排放的杂物。在数据库里也即是对应没有聚集索引。

2 聚集索引:一个表只有一个聚集索引且数据存放在聚集索引内。

3 非聚集索:是一个B-树(B-Tree)结构,它包含了索引键和指向数据行的指针。

我们可以在堆或聚集索引类型的表里创建非聚集索引。一个表的非聚集索引最多支持999个。在覆盖索引的应用场景下,可以定义非聚集索引时指定包含(include)其它字段。

4 唯一索引:唯一索引不允许表里的指定的列数据有重复的值,一个表可以有一个或多个唯一索引。

5 主键:主键是一个表里每行记录的唯一标识同时默认情况下也是聚集索引。

6 RID lookup 堆形式的表的执行计划里通过ROW id映射匹配其它非聚集索引字段的操作。

7 key lookup 聚集索引形式的表执行计划里通过主键映射匹配其它非聚集索引字段的操作。

聚集索引的演示案例

添加主键

-- 删除原有的索引
DROP INDEX EMPLOYEES.[IX_EMP_NAME]
ALTER TABLE EMPLOYEES ADD CONSTRAINT PK_EMPLOYEES_ID PRIMARY KEY(id);
GO

系统表查看当前表的类型

SELECT * FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.EMPLOYEES')

 

无索引下WHERE查询 

--查询名字是ABC 874000的员工信息。
-- 执行时点击SSMS里的“包括实际的执行计划按钮”菜单(或者用CTRL+M快捷键)。
SELECT * FROM EMPLOYEES 
WHERE NAME = 'ABC 874000'

 

这里因为是建了聚集索引,表数据存储在索引的叶子节点,所以应用的clustered index scan,读取的行数还是100W,所有实际执行的行数为1行。

非聚集索引下WHERE查询 

--在NAME字段上建立非聚集索引。
CREATE NONCLUSTERED INDEX IX_EMP_NAME ON EMPLOYEES(NAME)

-- 再次执行WHERE查询并含实际执行计划。
SELECT * FROM EMPLOYEES 
WHERE NAME = 'ABC 874000'

Key映射查找 

查询例子同上。

上例的执行计划中我们可以看到key lookup过程,这个映射查找出现的原因是我们的查询里name字段虽然可以在非聚集索引IX_EMP_NAME上支持获取到,但id、email、dept而这些信息则需要通过聚集索引里的记录ID来映射匹配到。为了区分堆形式的RID lookup,这里用的标识是key lookup。

 Key Lookup示意

 

 通过上图我们可以看到在非聚集索引的叶子节点里存放了索引字段和主键(如Employeeid),而通过主键可以找到记录的所有的字段。

以上是关于SQL Server 聚集索引 clustered index 非聚集索引Nonclustered Indexes键查找查找Key Lookup执行计划过程详解的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server索引的创建与维护

SQL Server索引的创建与维护

SQL Server 查询性能 - 聚集索引查找

为啥在sql server中每张表只能创建一个聚集索引?

SQL Server 内存优化表的索引设计

索引的访问-SQL Server