对聚集索引扫描和聚集索引搜索的澄清

Nar*_*dra 6 index sql-server execution-plan sql-server-2014

我已创建了80000条记录与一个表Cluster Index上的CustomerID列。当我查询以下语句时,执行计划的行为有所不同。任何人都可以澄清相同。

select * from customer
Run Code Online (Sandbox Code Playgroud)

显示集群索引扫描,所以这是正确的。

select * from customer where CustomerID=80000
Run Code Online (Sandbox Code Playgroud)

执行计划显示 ClusterIndex Seek,所以这是正确的。

select * from customer where CustomerID between 1 and 70000
Run Code Online (Sandbox Code Playgroud)

执行计划仍然显示ClusterIndex 求问为什么?

根据统计,行数为 90%,然后优化器必须使用“ClusterIndex Scan”,但它使用的是“Cluster Index Seek”,为什么?所有统计数据都是最新的,我已经检查了估计行和实际行,那么为什么优化器选择“集群索引搜索”来获取总记录中 90% 的行。

Pau*_*ite 10

执行计划仍然显示ClusterIndex 求问为什么?

b 树的初始查找是找到第一行,其中CustomerID >= 1

从那时起,存储引擎会记住当前的扫描位置,并每次父计划操作符请求一行时按索引顺序返回下一行。一旦遇到与谓词不匹配的行,扫描就会结束CustomerID <= 70000

效果是“seek”是一个初始的seek,然后是索引的部分有序扫描

这通常比扫描整个索引更有效,即使 90% 的行预计符合条件。在您的脑海中直截了当的关键点是,不会为每一行执行单独的 b 树搜索。


Sha*_*nky 2

这里的答案很简单,假设您表上只有一个聚集索引,并且您的查询如下

select * from customer where CustomerID between 1 and 70000
Run Code Online (Sandbox Code Playgroud)

在上面的情况下,优化器会首选seek,因为首先索引将根据条件搜索数据CustomerID=1,并找到与谓词匹配的第一行。然后它最终会沿着索引向下移动,直到到达范围的末尾,即7000获取相关数据。因此,所有查询引擎必须只读取相关页面才能为您提供信息,这样仍然符合搜索条件。