Sql server 为什么不是';查询中是否使用了特定的索引?

Sql server 为什么不是';查询中是否使用了特定的索引?,sql-server,tsql,Sql Server,Tsql,我有一个名为Workflow的表。它有3700万行。ID列(int)上有一个主键加上一个附加列。ID列是索引中的第一列 如果执行以下查询,则不会使用PK(除非使用索引提示) 如果改为执行此查询,则使用PK Select Distinct(SubID) From Workflow Where ID >= 786400000 我怀疑问题在于在查询中使用参数值(我必须这样做)。我真的不想使用索引提示。有解决方法吗?假设您的PK是一个标识或始终大于0,您可以尝试以下方法: Select Dist

我有一个名为Workflow的表。它有3700万行。ID列(int)上有一个主键加上一个附加列。ID列是索引中的第一列

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

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

Select Distinct(SubID) From Workflow Where ID >= 786400000

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

假设您的PK是一个标识或始终大于0,您可以尝试以下方法:

Select Distinct(SubID) 
From Workflow 
Where ID >= @LastSeenWorkflowID
    And ID > 0

通过添加第二个条件,可能会导致优化器使用索引搜索。

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

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

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

CREATE INDEX WorkflowSubId ON Workflow(ID, SubId);
或:


无论@LastSeenWorkflowID的值是多少,这样的索引都太好了,无法为您的查询传递。

这是局部变量生成次优计划的经典示例

您应该使用选项(重新编译),以便使用ID的实际参数值编译查询

有关更多信息,请参阅我的博客帖子:

这是非聚集索引吗?是否有聚集索引?@JNK-SQL Server 2008,PK是聚集索引index@Randy-那么执行计划显示了什么?表格扫描?聚集索引扫描“附加”列是否为子ID列?i、 e.你的索引是这个查询的覆盖索引吗?@Randy-它不知道你的参数有多选择性,因为你使用的是一个不等式,所以它选择了最好的全面计划,即扫描。
CREATE INDEX WorkflowSubId ON Workflow(ID, SubId);
CREATE INDEX WorkflowSubId ON Workflow(ID) INCLUDE (SubId);