【问题标题】:SQL query not using required index in SQL ServerSQL 查询未在 SQL Server 中使用所需的索引
【发布时间】:2011-11-29 08:44:47
【问题描述】:

我在表 A 上有两个非聚集索引:

  • detected_utc索引

键列:DETECTED_UTC ASC

包含的列:APPROVAL_STATUSIS_ROOTAGENTGUID

  • agentguid索引

键列:agentguid

现在查询正在使用agentguid 索引,耗时 1 分 17 秒。

但是如果我指定一个查询提示,比如

option (table hint(A, index(DETECTED_UTC)))

需要 4 秒。

为什么 SQL Server 没有在查询计划中考虑 detected_utc。可以修改查询以使其使用detected_utc 索引。我不想在我的查询中指定查询提示。

SELECT
    AUTO_ID
FROM
    (
      SELECT
        ROW_NUMBER() OVER ( ORDER BY A.DETECTED_UTC DESC ) AS ROWNUM
      , A.AUTO_ID
      , A.DETECTED_UTC
      FROM
        A
        INNER JOIN B
        ON A.AGENTGUID = B.AgentGUID
        LEFT JOIN C
        ON B.ParentID = C.AutoID
      WHERE
        ( DETECTED_UTC > DATEADD(day, -7, GETUTCDATE()) )
        AND ( APPROVAL_STATUS = '0' )
        AND IS_ROOT = '1'
        AND EXISTS ( SELECT
                        1
                     FROM
                        B epf
                     WHERE
                        epf.AgentGUID IS NOT NULL
                        AND epf.AgentGUID = A.AGENTGUID
                        AND epf.ParentID IN (
                        SELECT
                            AutoID
                        FROM
                            C
                        WHERE
                            AutoID IN ( SELECT
                                            NodeID
                                        FROM
                                            D
                                        WHERE
                                            D.GroupID IN ( 42 ) ) ) )
    ) AS TEMP
WHERE
    ROWNUM >= 1000
    AND ROWNUM < 1041
ORDER BY
    DETECTED_UTC DESC 

【问题讨论】:

  • 您是否尝试过更新统计信息? (sp_updatestats)
  • 可能是您的统计信息已过时。尝试使用UPDATE STATISTICS A WITH FULLSCAN更新统计信息
  • 我正在使用 sqlserver2008,我尝试使用全扫描选项更新统计信息,但仍然没有使用检测到的_utc 索引

标签: sql sql-server indexing


【解决方案1】:
  • 您的 JOIN 已开启 AGENTGUID
  • 您的 WHERE 使用 DETECTED_UTC, APPROVAL_STATUS, IS_ROOT

只有DETECTED_UTC 列在优化器的detected_utc 索引中有用:使用的其他列是包含的列。您的索引提示会覆盖这一点:我怀疑您会在计划中看到查找或假脱机或排序,并提示解决包含的列不是索引中的关键列

我希望其中之一会更有用

(AGENTGUID, DETECTED_UTC DESC, APPROVAL_STATUS, IS_ROOT) INCLUDE (AUTO_ID)
(DETECTED_UTC DESC, AGENTGUID, APPROVAL_STATUS, IS_ROOT) INCLUDE (AUTO_ID)

【讨论】:

    【解决方案2】:

    优化器估计 JOIN 是查询中最具选择性的部分。根据该估计,它正在做出选择,以使该联接尽可能具有高性能。

    您使用索引提示表明估计的选择性是错误的。更新统计信息和重新编译代码在这里可能会有所帮助,但很可能不会:查询非常复杂,最佳查询计划(以及使用哪个索引)将取决于存在的数据以及该数据的特征,在几个不同的表中。

    我会继续使用提示(如果您的数据的基本特征不会改变),或者按照 GBN 的建议创建复合索引。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      • 2012-07-31
      • 1970-01-01
      • 2011-05-10
      • 1970-01-01
      相关资源
      最近更新 更多