我刚刚在SSMS中检查了估计的执行计划。我注意到查询的查询成本为99%(相对于批处理)。然后,我检查了下面显示的计划。该成本几乎完全来自表A中的“聚集索引删除”。但是,缺失指数建议是针对表B.并且缺失指数影响据说是95%。
查询是DELETE
语句(显然),它依赖于嵌套循环INNER JOIN
和TableB
。如果根据计划的几乎所有成本都来自DELETE
操作,为什么索引建议在表B上 - 即使它是扫描 - 只有0%的成本? 95%的影响是否会影响扫描的可忽略的成本(列在0%上)而不是查询的总成本(据说几乎是所有批次的成本)?
如果可能,请解释IMPACT。这是计划:
答案 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
批次2
SELECT *
FROM T1
WHERE X = -1
UNION ALL
SELECT *
FROM T1
SELECT *
FROM T1
WHERE X = -1
第一个计划的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。因此,拥有一个可以更容易匹配这些行的索引将加快删除速度。