为什么查询中没有使用特定索引?

Ran*_*der 6 t-sql sql-server

我有一个名为Workflow的表.它有37M行.ID列(int)上有一个主键,还有一个附加列.ID列是索引中的第一列.

如果我执行以下查询,则不使用PK(除非我使用索引提示)

Select Distinct(SubID) From Workflow Where ID >= @LastSeenWorkflowID
Run Code Online (Sandbox Code Playgroud)

如果我执行此查询,则使用PK

Select Distinct(SubID) From Workflow Where ID >= 786400000
Run Code Online (Sandbox Code Playgroud)

我怀疑问题是在查询中使用参数值(我必须这样做).我真的不想使用索引提示.这有解决方法吗?

Rem*_*anu 3

请发布执行计划以及确切的表定义,包括所有索引。

当您使用变量时,优化器不知道查询将具有什么选择性,@LastSeenWorkflowID 可能会过滤掉工作流中除最后几行之外的所有行,或者可能包含所有行。生成的计划必须在这两种情况下都有效。有一个阈值,在该阈值处,对聚集索引的范围搜索比对非聚集索引的完整扫描更加昂贵,这仅仅是因为聚集索引要宽得多(它包括叶级别中的每一列),因此具有还有更多的页面需要迭代。生成的计划考虑了 @LastSeenWorkflowID 的未知值,在估计聚集索引查找的成本时可能会超过该阈值,因此它会选择扫描而不是非聚集索引。

您可以提供专门针对此查询的窄索引:

CREATE INDEX WorkflowSubId ON Workflow(ID, SubId);
Run Code Online (Sandbox Code Playgroud)

或者:

CREATE INDEX WorkflowSubId ON Workflow(ID) INCLUDE (SubId);
Run Code Online (Sandbox Code Playgroud)

无论 @LastSeenWorkflowID 的值如何,这样的索引对于您的查询来说都太糟糕了。