平台:SQL Server 2012
背景:我有两个相当大的日志表 - 每个日志表大约有 600k 条记录,使用 Pk/Fk 连接。为了便于讨论,我们将它们称为ReallyBigLog1 和ReallyBigLog2。查询(如下)的运行时间大约为 3.5 秒。 WHERE 子句包含三个不同的值。当被要求帮助改进这个查询时,我立即注意到 WHERE 子句中的项目没有索引。我沾沾自喜地建议添加索引——假设性能的提高会让我看起来像个英雄。然而,附加指标没有产生可测量的影响。
问题:给定以下查询,为什么索引 StartTime、EndTime 和 DateStamp 对查询时间没有可测量的影响?
查询
SELECT
IrreleventField1,
IrreleventField2,
IrreleventField3....
FROM [dbo].[ReallyBigLog1] AS [T1]
INNER JOIN [dbo].[ReallyBigLog2] AS [T2] ON [T1].[Id] = [T2].[Id]
WHERE ([T1].[EndTime] IS NOT NULL) AND ([T1].[StartTime] IS NOT NULL) AND ([T2].[DateStamp] >= '2017-5-16 00:00:00')
索引
CREATE NONCLUSTERED INDEX [ix_RecommendedIndex]
ON [dbo].[ReallyBigLog1]
([StartTime] , [EndTime])
CREATE NONCLUSTERED INDEX [IX_DateStamp]
ON [dbo].[ReallyBigLog2]
([DateStamp])
执行计划
5 SELECT
4 Compute Scalar
3 Merge Join / Inner Join Merge:([dbo].[ReallyBigLog1].[Id] [T2]=[dbo].[ReallyBigLog1].[Id] [T1]), Residual:([dbo].[ReallyBigLog2].[Id] as [T2].[Id]=[dbo].[ReallyBigLog1].[Id] as [T1].[Id])
1 Clustered Index Scan Predicate:([dbo].[ReallyBigLog1].[StartTime] as [T1].[StartTime] IS NOT NULL AND [dbo].[ReallyBigLog1].[EndTime] as [T1].[EndTime] IS NOT NULL), ORDERED FORWARD [dbo].[ReallyBigLog1].[PK_dbo.ReallyBigLog1] [T1]
2 Clustered Index Scan Predicate:([dbo].[ReallyBigLog2].[DateStamp] as [T2].[DateStamp]>='2017-05-16 00:00:00.000'), ORDERED FORWARD [dbo].[ReallyBigLog2].[PK_dbo.ReallyBigLog2] [T2]
编辑(表格组成)
SELECT
(SELECT COUNT(*) FROM ReallyBigLog1 WHERE StartTime IS NULL) as NullStartTime,
(SELECT COUNT(*) FROM ReallyBigLog1 WHERE EndTime IS NULL) as NullEndTime,
(SELECT COUNT(*) FROM ReallyBigLog1) as Log1Count,
(SELECT COUNT(*) FROM ReallyBigLog2 WHERE DateStamp > '2017-5-16 00:00:00') AS DateStampUsage,
(SELECT COUNT(*) FROM ReallyBigLog2) AS Log2Count
DateStampUsage Log2Count NullStartTime NullEndTime Log1Count
443038 651929 33748 34144 509545
最佳答案
ix_RecommendedIndex
的帮助非常有限,除非你有很多空值。
在这里,真正重要的索引是 Ids
和 IX_DateStamp
。由于 WHERE 子句中似乎有大量匹配数据,因此优化器更喜欢聚集表扫描(以合并 Id
)。
加快速度的一种可能是在 IX_DateStamp
上使用聚集索引,但它会对其他查询产生性能副作用,因此应首先在测试环境中强调。
如果您可以向 EXPLAIN 提供统计信息,可能有助于更好的诊断。
编辑:根据提供的统计信息,我不知道如何仅使用索引来使其更快。有太多数据需要解析(超过两个表的一半)。您可能需要在另一个表中合并数据设备,或者在二进制级别优化数据(较小的记录大小以加快扫描速度)。
关于sql - 为什么这个索引不能提高查询性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44597408/