估计与实际行差异(实际远小于估计) - 排序

Pet*_*ith 9 performance xml sql-server query-performance

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

Mik*_*son 10

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

使用此表:

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

这个相当简单的 XML 查询:

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

将为您返回一行,但返回的估计行数为 200。无论您在该行的 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)
Run Code Online (Sandbox Code Playgroud)

这将使我估计返回 5 行。

在此处输入图片说明

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

除了Michael Rys演讲外,我没有找到任何关于估算规则的文件,他说:

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