添加看似完美的索引会对查询性能产生意外的负面影响......
-- [Data] has a predictable structure and a simple clustered index of the primary key:
ALTER TABLE [dbo].[Data] ADD PRIMARY KEY CLUSTERED ( [ID] )
-- Joins on itself looking for a certain kind of "overlapping" records
SELECT DISTINCT
[Data].ID AS [ID]
FROM
dbo.[Data] AS [Data]
JOIN
dbo.[Data] AS [Compared] ON
[Data].[A] = [Compared].[A] AND
[Data].[B] = [Compared].[B] AND
[Data].[C] = [Compared].[C] AND
([Data].[D] = [Compared].[D] OR [Data].[E] = [Compared].[E]) AND
[Data].[F] <> [Compared].[F]
WHERE 1=1
AND [Data].[A] = @A
AND @CS <= [Data].[C] AND [Data].[C] < @CE -- Between a range
到目前为止,[数据]有大约25万条记录,10%到50%的数据满足where子句,具体取决于@ A,@ CS和@CE。按原样,查询10%时查询返回约300行,查询50%数据时返回3000行需要30秒。
奇怪的是,估计/实际执行计划表示两个并行聚集索引扫描,但聚簇索引只是ID,这不是查询条件的一部分,只有输出。 ??
如果我添加这个手工制作的[IDX_A_B_C_D_E_F]
索引,我完全希望它可以提高性能,那么查询速度会降低8倍(10%时为8秒,50%时为4分钟)。估计/实际执行计划显示索引搜索,这似乎是正确的做法,但为什么这么慢?
CREATE UNIQUE INDEX [IDX_A_B_C_D_E_F]
ON [dbo].[Data] ([A], [B], [C], [D], [E], [F])
INCLUDE ([ID], [X], [Y], [Z]);
数据引擎优化向导建议使用类似的索引,但与此方法的性能没有明显差异。将AND [Data].[F] <> [Compared].[F]
从连接条件移动到where子句对性能没有影响。
我需要这些和其他索引用于其他查询。我确信我可以暗示查询应该引用聚集索引,因为它目前正在赢 - 但我们都知道它没有尽可能优化,没有适当的索引,我可以预期,附加数据会使性能变差。
是什么给出了?
==编辑==
对于Gail,这是执行计划。当然,引用索引的索引是可用索引查询的索引。这与我对聚集索引扫描的原始描述略有不同 - 我删除了自动生成PK索引以进行测试而无法将其取回(?),因此这根本没有任何索引,因此表扫描。查询计划看起来不同,但性能没有明显变化。 (表扫描速度很快)
execution plans http://www.imagechicken.com/uploads/1276732894073081600.png
答案 0 :(得分:2)
它正在进行CI扫描,因为CI是实际数据。索引只是实际数据的占位符。
在50%的回复查询中,索引搜索肯定是不正确的事情,并且即使在10%的回报率上也很少使用。通常,如果它超过百分之几,它就会扫描(这就是为什么在较小的表上你可以指望扫描几乎每次都发生)。
我建议确保该表的统计信息是最新的,并且可能确保索引本身不需要维护。
更新状态 - http://msdn.microsoft.com/en-us/library/ms187348.aspx