估计行与实际行之间的差异(实际比估计的要小得多)-排序


8

我正在运行一个查询,该查询正在处理XML文档中的某些节点。我估计的子树成本为数百万美元,这似乎全部来自sql服务器对我通过XPath从xml列提取的某些数据执行的排序操作。排序操作估计的行数约为1900万,而实际的行数约为800。查询本身运行得很好(1-2秒),但是差异让我想知道查询性能以及为什么这样做相差这么大?


2
这可能是由于过时的统计信息造成的,但如果没有更多信息(包括表结构/索引,查询以及实际的(而不是估计的)执行计划),实际上是无法分辨的。
亚伦·伯特兰

1
根据我的经验,涉及分解XML的查询计划总会夸大成本估算。就像这样,如果查询在执行时间方面表现良好,我将忽略成本估算数字。我不知道为什么要这么做,但是可能与不知道将要使用多少XML作为输入有关。但是,如果您的目标是提高查询的性能,那么我发现做到这一点的一种方法是使用XML模式集合,就像我在此处博客所写的那样。
乔恩·塞格尔

Answers:


9

XML列上没有生成统计信息。根据查询XML时使用的表达式来猜测估计值。

使用此表:

create table T(XMLCol xml not null)
insert into T values('<root><item value = "1" /></root>')

这个相当简单的XML查询:

select X.N.value('@value', 'int')
from T
  cross apply T.XMLCol.nodes('root/item') as X(N)

将为您提供返回的一行,但返回的估计行为200。无论您将XML填充到该行的XML列中是多少XML或多少XML,都将返回200。

这是查询计划,其中显示了估计的行数。

在此处输入图片说明

一种改善或至少改变估计值的方法是为查询优化器提供有关XML的更多信息。在这种情况下,因为我知道root真的是在XML根节点,我可以重写本查询。

select X2.N.value('@value', 'int')
from T
  cross apply T.XMLCol.nodes('root[1]') as X1(N)
  cross apply X1.N.nodes('item') X2(N)

这将使我估计返回了5行。

在此处输入图片说明

查询的重写可能不会加快XML的分解速度,但是如果估计更好,则查询优化器可能会为其余查询做出更明智的决策。

除了迈克尔·赖斯(Michael Rys)演讲中说:我没有找到任何有关估算规则的文件,他说:

基本基数估计始终为10,000行!
基于推送路径过滤器的一些调整

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.