sql - 为什么这个索引不能提高查询性能

标签 sql sql-server sql-server-2012 database-performance sql-tuning

平台: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 的帮助非常有限,除非你有很多空值。

在这里,真正重要的索引是 IdsIX_DateStamp。由于 WHERE 子句中似乎有大量匹配数据,因此优化器更喜欢聚集表扫描(以合并 Id)。

加快速度的一种可能是在 IX_DateStamp 上使用聚集索引,但它会对其他查询产生性能副作用,因此应首先在测试环境中强调。

如果您可以向 EXPLAIN 提供统计信息,可能有助于更好的诊断。

编辑:根据提供的统计信息,我不知道如何仅使用索引来使其更快。有太多数据需要解析(超过两个表的一半)。您可能需要在另一个表中合并数据设备,或者在二进制级别优化数据(较小的记录大小以加快扫描速度)。

关于sql - 为什么这个索引不能提高查询性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44597408/

相关文章:

sql-server - Max() 函数不返回最大值

sql-server - 每晚将 Excel 电子表格导入 mysql 数据库

sql-server - 在 SQL Server 中为每条记录创建行到列

mysql - SQL 内连接使用

sql - 在 View 中将数据类型 nvarchar 转换为数字时出错

mysql - 如何在不使用 CONCAT() 的情况下连接字段

sql-server - SQL Server 2016 始终在已发布的 IIS 上加密超时

sql-server - Hibernate Query在系统中运行缓慢,但直接运行时速度很快

sql - 通过 SQL 返回硬编码值的不同方式

sql-server - SSRS 是否同时运行多个查询?