包含的列在Seek运算符中使用

问题描述

考虑一个具有两个非聚集索引的表,并查询

1 INDEX_1 on table (column1,column2,column3)
2 INDEX_2 on table (column1) INCLUDED (column2,column3)

    SELECT column3
    FROM   table
    WHERE  column1 = 100 columnn2 =  100

由于某些原因,sql Server使用INDEX_2。 两个索引的执行计划都相同(除了Seek运算符中的对象) 另外,两者的逻辑读取时间相同。 如果索引未按INDEX_2排序,怎么可能在column2上以这种条件执行搜寻运算符

解决方法

如果索引未按column2排序,如何在INDEX_2上以这种条件执行搜索运算符

“索引搜索”会搜索索引中的某个位置,但随后可能会沿着叶级页面从该点开始进行扫描,这些页面按照索引排序顺序存储在一个双向链接的列表中。

因此,它实际上更像是“搜索+扫描”。从聚簇索引中进行选择时,您会看到相同的计划,因为包含列的索引属于微型聚簇索引。

例如在Adventureworks中

SELECT SalesOrderID,*
FROM Sales.SalesOrderDetail
WHERE SalesOrderID = 43892
  AND ProductID = 758

将为您提供一个可以读取多行的索引查找:

enter image description here

寻找包含该SalesOrderID行的第一页,然后进行扫描,直到找到具有该ProductID的所有行。当操作员找到具有不同SalesOrderID的页面时,就完成了。

但是,如果(column1,column2,column3)是聚簇索引键,则查询将是单行Seek。所有非唯一非聚集索引都将所有聚集索引列添加为索引键列,并在物理上存储为唯一索引。