sql-server - 帮助进行简单查询 - 为什么不使用索引?

标签 sql-server

我有以下查询:

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/

相关文章:

sql - 如何查询 SQL Server 2008 数据库的名字和姓氏以及按相关性排序?

sql - 将主键添加到数据库中的一些现有表

mysql - 将 MySQL 数据库导出到 Sql Server 数据库的最佳方法

sql-server - 排序列上的索引

sql-server - 较长日期范围内的 SQL Server 查询性能

sql-server - 没有文件可下载时,如何避免SSIS FTP任务失败?

mysql - SQL按学生年级排序

sql-server - SQL Server 动态 Order By in query,不同数据类型

SQL Server 2017 Express LocalDB 可用吗?

mysql - 带有 if 语句的 SQL 事务