使用SQL查询中索引之外的列进行密钥查找

时间:2018-03-02 17:23:07

标签: sql-server-2012 sql-execution-plan query-tuning

我的查询如下

SELECT ActivityId,
       AnotherId,
       PersonId,
       StartTime AS MyAlias
FROM   Activity
WHERE  DeletedStatus='Active' AND
       StartTime>='2018-02-01'AND StartTime<='2018-02-08'

正在使用的执行计划在这里

Execution Plan

Index1定义为:

CREATE NONCLUSTERED INDEX Index1 ON Activity
(
    StartTime
)

索引2定义为:

CREATE CLUSTERED INDEX Index2 ON Activity
(
     EndTime
     StartTime
)

优化器正在使用Index1上的索引查找,然后使用键查找,因为ActivityId,AnotherId,PersonId位于SELECT列表中但不在索引中。这对我来说很有意义。

但是,以下事情让我很困惑:

  • 当DeletedStatus不在索引中但是在WHERE子句中时,为什么优化器能够使用Index1进行索引查找?
  • 当Index1中没有该列时,为什么Index1中的输出列表包含EndTime?
  • 当Index2中没有一列属于Index2时,如何使用Index2输出ActivityId,AnotherId,PersonId?
抱歉,我对计划和查询进行了伪匿名,所以我希望我做得对!

1 个答案:

答案 0 :(得分:1)

  

为什么优化器能够使用Index1来执行索引查找   DeletedStatus不在索引中但在WHERE子句中?

WHERE子句还包含StartDate,因此可以使用提供的StartDate值然后进行范围扫描来执行搜索。键查找包括'Active'谓词,用于过滤每个WHERE子句的行,因为该列未包含在索引中。

  

为什么Index1中的输出列表包含该列的EndTime   Index1中没有出现?

所有非聚簇索引都隐式包含聚簇索引键作为行定位器,类似于显式包含的列。

  

如何使用Index2输出ActivityId,AnotherId,PersonId   这些列中没有一列在Index2中吗?

聚簇索引叶节点是实际数据行,因此所有列都可用。