当计划中未使用该索引时,为什么在SQL Server中添加索引会减慢查询速度?

问题描述 投票:1回答:2

我很难过。如果我删除查询未使用的索引,则查询从46秒减少到6秒。

这是查询:

SELECT TOP (10) 
[Extent1].[alarm_class_id] AS [alarm_class_id], 
[Extent2].[domain_id] AS [domain_id], 
[Extent3].[description] AS [description], 
[Extent1].[list_id] AS [list_id], 
[Extent2].[list_source] AS [list_source], 
[Extent1].[list_detail_id] AS [list_detail_id], 
[Extent1].[plate] AS [plate], 
[Extent1].[notes] AS [notes], 
[Extent1].[locale_id] AS [locale_id], 
[Extent1].[end_date] AS [end_date], 
[Extent2].[eoc_list_id] AS [eoc_list_id], 
[Extent2].[list_type_id] AS [list_type_id]
FROM   [dbo].[list] AS [Extent2]
INNER JOIN [dbo].[ron_list_detail] AS [Extent1] ON [Extent1].[list_id] = [Extent2].[list_id]
INNER JOIN [dbo].[domain_lookup] AS [Extent3] ON [Extent2].[domain_id] = [Extent3].[domain_id]
WHERE ([Extent2].[domain_id] IN (7)) AND (([Extent1].[end_date] IS NULL) OR ([Extent1].[end_date] > (SysDateTimeOffset())))

这是索引:

CREATE NONCLUSTERED INDEX [ron_CI_list_detail-list_id-plate] 
ON [dbo].[ron_list_detail] ([list_id] ASC, [plate] ASC)
         WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
               SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
               ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
GO

附加信息:除非我提供提示,否则查询计划不会使用此索引。如果我提供提示,则查询在一秒钟之内。

我很困惑 - 想法? (会显示查询计划,但我无法弄清楚如何粘贴图像)

sql sql-server performance indexing
2个回答
3
投票

我能想到的其中一个原因是其他指数的过时统计数据。以下是它可能发生的方式:

  1. 您现有的索引已经过时的统计信息会欺骗优化者认为它们更适合您的查询。结果,不使用新索引;
  2. 当涉及到实际的查询执行时,由此产生的计划错过很多次并且查询需要很长时间才能运行;
  3. 当您使用提示确定索引时,查询优化器别无选择,只能使用它,并且运行速度更快(应该如此)。

在优化索引时,请确保所有索引都是新重建的,并且所有统计信息都会更新(不一定使用fullscan,默认模式通常也能正常工作)。最有可能的是,在执行类似的操作之后

alter index all on [dbo].[ron_list_detail] rebuild;

该计划可能会在不需要任何提示的情况下理顺。

另一件事是您的索引对于此特定查询看起来不是最佳的。我宁愿考虑domain_id, list_id,因为plate列仅作为输出返回,并且不用于任何连接条件。


0
投票

原来它是查询中的TOP。

SELECT ...很快SELECT TOP(1191)...慢一点SELECT TOP(1192)....很快

任何数字<= 1191都是慢的任何数字> = 1192是快的没有顶部是快的

奇怪的!!!

© www.soinside.com 2019 - 2024. All rights reserved.