我有以下查询:
SELECT MAX([LastModifiedTime]) FROM Workflow
Workflow 表中大约有 400M 行。 LastModifiedTime 列上有如下索引:
CREATE NONCLUSTERED INDEX [IX_Workflow_LastModifiedTime] ON [dbo].[Workflow]
(
[LastModifiedTime] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100)
上述查询执行需要 1.5 分钟。为什么 SQL Server 不使用上述索引并简单地检索索引中的最后一行以获得最大值?
顺便说一句,此查询的查询计划显示正在对上述索引执行索引扫描
。
谢谢。
最佳答案
神秘的是查询优化器的方式...
如果可能,我建议您像这样更改查询:
SELECT TOP (1) [LastModifiedTime]
FROM Workflow
ORDER BY [LastModifiedTime] DESC;
这在语义上是相同的,优化器将不再考虑使用 MAX 聚合和扫描(显然它现在正在这样做)。它可能会考虑在工作表中执行 SORT,但希望这种计划的估计成本会比逆序查找的成本大得多。
至于为什么优化器选择了一个明显糟糕的计划,通常涉及很多因素,并且很难仅从 SO 帖子中诊断出来。一般来说,拥有 ASC 索引并不总是可以替代缺少 DESC 索引,并且您的特定列统计信息(分布)可能已经达到查询优化器内部的某个临界点,它决定选择扫描+聚合而不是反向扫描+顶部。
关于sql-server - 帮助进行简单查询 - 为什么不使用索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2923950/