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

Sql server 简单查询帮助-为什么不使用索引?,sql-server,Sql Server,我有以下疑问: SELECT MAX([LastModifiedTime]) FROM Workflow 工作流表中大约有400M行。LastModifiedTime列上有一个索引,如下所示: CREATE NONCLUSTERED INDEX [IX_Workflow_LastModifiedTime] ON [dbo].[Workflow] ( [LastModifiedTime] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE

我有以下疑问:

SELECT MAX([LastModifiedTime]) FROM 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不使用上面的索引并简单地检索索引中的最后一行以获得最大值

顺便说一句,此查询的查询计划显示正在对上述索引进行索引扫描


谢谢。

你能从执行计划中看出它是否在使用索引吗?如果没有,上次分析表/索引是什么时候?如果从未对其进行过分析,可能SQL server仍然认为其中只有100行,因此进行表扫描会更快。

我有一个表,其中有一个类似的日期时间字段,假设这是您的数据类型,有400万行,占您行数的1%,但几乎在我单击“执行”时,相同的查询返回。我的索引与你的索引几乎相同:

CREATE NONCLUSTERED INDEX [IX_PartViewTrack_SearchDate] ON [dbo].[PartViewTrack] 

(
[SearchDate] 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) ON [PRIMARY]
执行计划显示索引扫描

只是为了露齿而笑——放下指数,看看需要多长时间

SELECT MAX([LastModifiedTime]) FROM Workflow with(nolock)

这更快吗?

这是一个黑白相间的问题,对我来说没有一个明显的答案。这里有一些相当愚蠢的想法,只是想澄清一下

这是一张桌子吗?如果是视图,则为底层 结构可能会成为阻碍。我 忘了,你能建立一个非集群的 物化视图上的索引

有争论吗?如果其他用户 在门上有长期的锁 桌子,那可能会慢下来。 而且,非常频繁的更新 可能会把它扔掉

查询计划显示索引扫描 正在运行。是索引引用 这个指数?还有其他索引吗?聚集索引? 可能不是问题,但是乱涂乱画 这里有很多想法

您使用模式吗?索引已打开 工作流,但查询没有 指定dbo。就像我说的, 在这里寻找想法


所有这些听起来都很蹩脚,但如果没有亲身体验,这些问题可能很难解决

这里有一个长期问题:我发现Oracle有时需要一个字段不允许空值,然后才能对其使用索引。SQL Server中是否有类似的限制?

查询优化器的方法很神秘

如果可能,我建议您更改以下查询:

SELECT TOP (1) [LastModifiedTime]
FROM Workflow 
ORDER BY [LastModifiedTime] DESC;
<>这是语义上相同的,优化器将不再考虑使用它现在所做的最大聚合和扫描。它可以考虑在工作表中进行排序,但希望这样的计划的估计成本要比反向次序搜索的成本大得多。
至于为什么优化器会选择一个明显不好的计划,通常会涉及很多因素,仅仅从一篇文章中很难诊断。一般来说,拥有ASC索引并不总是可以代替缺少DESC索引,并且您的特定列统计信息分布可能在查询优化器中遇到了某个转折点,它决定选择“扫描+聚合”而不是“反向扫描+顶部”。

首先使用命令分析索引

DBCC SHOW_STATISTICS (table_name, index_name)
检查您的索引是否覆盖了整个表。如果没有,请尝试使用更新您的统计信息

UPDATE STATISTICS table_name

这个专栏上的索引是大约两个小时前刚刚添加的。他们的查询计划显示正在对索引进行索引扫描。@Randy Jut出于好奇,此查询需要多长时间:按LastModifiedTime desc从工作流顺序中选择前1名LastModifiedTime您可以尝试更新统计数据dbo.WorkFlow或更新统计数据dbo.WorkFlow IX_WorkFlow_LastModifiedTime,并查看这是否有任何区别???@marc_s-它正在使用索引,但正在扫描它。为什么不降到最后一排呢?这将是最大值。除非当索引中有4亿行时,需要1:30才能下拉到最后一行?是的,如果您更新统计信息,查询优化器可能会注意到需要扫描的行太多-并找到其他策略以获得所需的结果…您是否尝试添加DESC索引?@Lieven-是的,我尝试了DESC索引。但它仍然想进行索引扫描,可能会稍微快一点,但真正的问题是它是在进行索引扫描,而不是搜索。添加withnolock不会改变这一点。