添加看似完美的索引会对查询性能产生意外的不利影响…
-- [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%时,查询需要1秒钟返回大约300行,查询50%数据时,查询需要30秒钟返回3000行。
奇怪的是,估计的/实际的执行计划显示了两个平行的
聚集索引扫描
,但是聚集索引只是id的一部分,而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子句在性能上没有区别。
对于其他查询,我需要这些索引和其他索引。我敢肯定,我可以暗示查询应该引用聚集索引,因为这是目前的胜利-但我们都
知道
它并没有尽可能的优化,如果没有适当的索引,我可以预计使用额外的数据,性能会变得更差。
给出了什么?
=编辑=
对于盖尔来说,这是执行计划。当然,引用索引的那个是用可用索引查询的那个。这与我对聚集索引扫描的原始描述稍有不同-我删除了用于测试的自动生成pk索引,但无法将其返回(?),所以这根本没有任何索引,因此表扫描。查询计划的外观不同,但性能没有明显变化。(扫描速度最快)
execution plans http://www.imagechicken.com/uploads/1276732894073081600.png
Indexed.sqlplan
Nonindexed.sqlplan