执行计划显示索引搜索为“空”'查询非聚集索引

时间:2016-01-28 02:28:18

标签: sql-server sql-server-2008-r2

据我所知,具有空值的列上的索引将无助于'为空'查询为null匹配所有内容。所以我期待在执行计划中看到索引扫描或全表扫描。

然而,当我查看查询的实际执行计划时,我发现它正在进行Index Seek。

这怎么可能?或者它是红鲱鱼?

enter image description here

1 个答案:

答案 0 :(得分:0)

正如我理解你的问题,你担心为什么查询优化器chosses索引搜索当所有行只有NUll数据时它应该有索引扫描或全表扫描,因为它最终读取所有行没有我的可空列。 这怎么可能?或者它是红鲱鱼?

第一, 看看NONCLUSTERD INDEX SEEK TO TOOLTIP的定义“

  

扫描非集群指数的一个特定范围

Seek并不总是通过b-tree结构寻求它的搜索范围 所以实际上你可以说在sql server中有两种类型的搜索

  

(1)Singleton Lookups:仅当它直接通过B树时   root到leaf用于完全匹配的行,并且仅在unique中发生   索引与euality谓词。

     

(2)SEEK PLUS范围扫描:当它通过B树根到叶子时   然后在一个方向上通过另一片叶子执行范围扫描   直到它匹配匹配的行。

所以在你的情况下它实际上是一个SEEK PLUS Range Scans,索引中的所有行都会对数据进行检验。

那为什么不进行全表扫描?

因为您使用谓词“SomeIO为null”
someid有非独特的非聚集索引 并且INDEX页面大小小于表格/ custered INDEX的页面大小,因此总是更好地阅读更多的页面。

为什么它没有做完全的INDEX SCAN为什么选择INDEX SEEK?

为此,我会用寻找和扫描相同的查询来说明你的执行计划

enter image description here

enter image description here

您可能知道Sql server创建逻辑表达式查询的多个物理计划, 并选择总成本最低的查询计划。 因此,您可以在上面的图像中看到索引查找的查询计划总体成本低于索引扫描(上述计划中成本较低的原因之一是估计行大小)。 在现实世界中你可以比较两者。

对于我的TestTable系统,

PAGE读取和扫描计数相同

扫描计数1,逻辑读取3179,

  

WARM CHACHE结果:

基线是5次执行而没有paralllism

  ITERATOR      max time   min time    avg time
 INDEX SEEK     122 ms.    112 ms.     116 ms
 INDEX SCAN     149 ms     139 ms      145 Ms

在我的系统上,Seek也获胜了。

现在,完全不同的问题就是这个有价值的指数。

  

OP OPMENT后。 sql server索引空值吗?

是的......