4

我在 SQL Server 上有一个大约 100 万行的表。它有一个 ID (PK)、一个状态 (int) 和一个日期时间列。我还在日期时间列上创建了一个索引。

现在我发现了一个我不明白的效果。

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

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

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

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

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

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

有解释吗?

4

1 回答 1

5

status不包含在索引中,datetime因此它需要对每个匹配行进行键查找以检索此值。

随着范围的增长(因此需要查找的数量),它估计仅扫描整个(覆盖)聚集索引以避免查找会更快。在您的情况下可能不正确。它从一个计划切换到另一个计划的点被称为临界点

您应该检查估计的行数与实际的行数是否不正常(也许自上次更新统计信息以来,已删除了一些与范围匹配的行)。

Or maybe the index scan is more expensive than the costing assumptions assume due to high levels of fragmentation or for some other reason the costing assumptions made do not reflect the actual relative performance in your environment.

于 2012-10-11T18:43:15.213 回答