为什么SQL Server没有使用Index进行非常相似的日期时间查询?

时间:2012-10-11 18:34:47

标签: sql indexing primary-key

我在SQL Server上有一个表,大约有100万行。 它有一个ID(PK),一个status(int)和一个datetime列。 我还在datetime列上创建了一个索引。

现在我发现了一种效果,我不明白。

SELECT status
FROM table
WHERE dateTime BETWEEN '2010-01-01T00:00:00' AND '2010-01-02T12:00:00'

此语句返回3664行。它运行大约150ms,执行计划显示它使用键查找进行索引搜索。

现在,如果我将其更改为以下(只需将小时从12更改为13):

SELECT status
FROM table
WHERE dateTime BETWEEN '2010-01-01T00:00:00' AND '2010-01-02T13:00:00'

此语句返回3667行。它运行大约600毫秒,并且exuction计划显示它使用主键!

我只是不明白。对于3667和更多行,它总是使用主键,即使搜索速度要快得多。

有解释吗?

1 个答案:

答案 0 :(得分:5)

status未包含在datetime的索引中,因此需要对每个匹配行执行密钥查找以检索此值。

随着范围的增长(以及因此需要的查找次数),它估计扫描整个(覆盖)聚簇索引以避免查找会更快。你的情况可能不正确。它从一个计划切换到另一个计划的点称为the tipping point

您应该检查估计的行数与实际行数是否超出了重要性(可能是自上次更新统计数据以来已删除了与该范围匹配的某些行)。

或者索引扫描比成本假设假设更昂贵,因为碎片水平较高或由于某些其他原因costing assumptions所做的不能反映环境中的实际相对性能。