SQL Server 2008执行计划中“缺失索引影响%”的含义是什么?

时间:2014-01-02 17:52:18

标签: sql-server

我刚刚在SSMS中检查了估计的执行计划。我注意到查询的查询成本为99%(相对于批处理)。然后,我检查了下面显示的计划。该成本几乎完全来自表A中的“聚集索引删除”。但是,缺失指数建议是针对表B.并且缺失指数影响据说是95%。

查询是DELETE语句(显然),它依赖于嵌套循环INNER JOINTableB。如果根据计划的几乎所有成本都来自DELETE操作,为什么索引建议在表B上 - 即使它是扫描 - 只有0%的成本? 95%的影响是否会影响扫描的可忽略的成本(列在0%上)而不是查询的总成本(据说几乎是所有批次的成本)?

如果可能,请解释IMPACT。这是计划: Execution Plan

4 个答案:

答案 0 :(得分:11)

假设缺失影响%的解释与sys.dm_db_missing_index_group_stats系统视图中的avg_user_impact列的解释相同或相似,则缺少影响%表示(或多或少):

  

如果这样,用户查询可能会遇到的平均百分比收益   缺失的索引组已经实施。该值表示查询   如果这个缺失的指数,成本将平均下降这个百分比   小组已经实施。

答案 1 :(得分:10)

这是批处理中的查询27。

它显示的影响可能实际上属于完全不同的陈述(1-26)。

这似乎是对SSMS中估计计划的影响显示方式的问题。

下面的两个批次包含相同的两个语句,顺序颠倒过来。请注意,在第一种情况下,它声称​​两个语句对99.38和第二49.9818的影响同等有帮助。

因此,它显示了对该缺失索引遇到的第一个实例的估计影响 - 不是与该陈述实际相关的实例。

我没有在实际执行计划中看到这个问题,并且即使在估算的计划中,每个语句旁边的计划XML中也会显示正确的影响。

我添加了有关此问题here的Connect项目报告。 (虽然可能你遇到了另一个问题,因为10%的影响似乎是计划中包含的缺失索引细节的截止点,很难看出这可能与问题中描述的原因相同)

示例数据

CREATE TABLE T1
  (
     X INT,
     Y CHAR(8000)
  )

INSERT INTO T1
            (X)
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY @@spid)
FROM   sys.all_objects o1,
       sys.all_objects o2 

批次1

SELECT *
FROM T1
WHERE X = -1

SELECT *
FROM T1
WHERE X = -1
UNION ALL
SELECT *
FROM T1

enter image description here

批次2

SELECT *
FROM T1
WHERE X = -1
UNION ALL
SELECT *
FROM T1

SELECT *
FROM T1
WHERE X = -1

enter image description here

第一个计划的XML(严重截断)如下所示,表明正确的信息在计划本身中。

<?xml version="1.0" encoding="utf-16"?>
<ShowPlanXML>
  <BatchSequence>
    <Batch>
      <Statements>
        <StmtSimple StatementCompId="1">
          <QueryPlan>
            <MissingIndexes>
              <MissingIndexGroup Impact="99.938">
                <MissingIndex Database="[tempdb]" Schema="[dbo]" Table="[T1]">
                  <ColumnGroup Usage="EQUALITY">
                    <Column Name="[X]" ColumnId="1" />
                  </ColumnGroup>
                </MissingIndex>
              </MissingIndexGroup>
            </MissingIndexes>
          </QueryPlan>
        </StmtSimple>
      </Statements>
      <Statements>
        <StmtSimple StatementCompId="2">
          <QueryPlan>
           <MissingIndexes>
              <MissingIndexGroup Impact="49.9818">
                <MissingIndex Database="[tempdb]" Schema="[dbo]" Table="[T1]">
                  <ColumnGroup Usage="EQUALITY">
                    <Column Name="[X]" ColumnId="1" />
                  </ColumnGroup>
                </MissingIndex>
              </MissingIndexGroup>
            </MissingIndexes>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
  </BatchSequence>
</ShowPlanXML>

答案 2 :(得分:1)

感谢所有人的信息。马丁史密斯我相信确实发现了一个错误,虽然我不确定它是否与我所看到的相同。事实上,我不确定我的问题是错误还是设计问题。让我详细说明一些新的意见:

在查看这个相当大的执行计划(62个查询)时,我注意到我在原始问题中提到的缺失索引建议(以及相应的影响%)几乎列在62查询批次中的每个查询中。奇怪的是,许多这些查询甚至没有调用建议索引的表!在观察完之后,我打开了XML并搜索了元素'MissingIndexes',它显示了大约10个不同的索引,它们都有不同的影响%,当然。为什么执行计划没有在视觉上显示,而是只显示一个Missing Indezx,我不知道。我认为这是1)一个错误或2)它只显示具有最高影响%的缺失索引 - 这是我在整个计划中看到的那个。

如果您遇到这种情况,也可以提出建议:在可视化执行计划中熟悉XML。搜索xml元素'MissingIndexes'并将其与语句匹配以获得正确的结果。

我也读过微软http://technet.microsoft.com/en-us/library/ms345524(v=sql.105).aspx 丢失的索引统计数据来自一组DMV。如果影响%实际上是来自这些DMV,那么我还假设影响%基于多个,而不仅仅是执行计划中的查询/陈述是推荐的索引。因此,请用一粒盐,并根据您自己对数据库的了解明智地使用它们。

我将离开这个开放式的结果,并没有将任何标记为“答案”。随意欢呼大家!

再次感谢。

答案 3 :(得分:0)

好的,让我看看我能否澄清一下。

0%的其他操作仍然会有成本,因为循环上的DELETE占用了处理器和IO时间的绝大部分。但这并不意味着那些其他操作没有处理器/内存/ IO成本,可以通过添加该索引来改进此查询。特别是如果你正在做一个循环,基本上是映射到tableB的一个记录,然后一遍又一遍地删除tableA。因此,拥有一个可以更容易匹配这些行的索引将加快删除速度。