奇数流聚合行为

Mik*_*son 11 sql-server execution-plan

询问:

declare @X xml = '
<item ID = "0"/>
<item ID = "1"/>
<item/>
<item/>';

select I.X.value('@ID', 'int')
from @X.nodes('/item') as I(X);
Run Code Online (Sandbox Code Playgroud)

结果:

-----------
0
1
NULL
NULL
Run Code Online (Sandbox Code Playgroud)

执行计划:

在此处输入图片说明

顶部分支将 XML 分解为四行,底部分支获取属性的值ID

令我感到奇怪的是从 Stream Aggregate 运算符返回的行数。来自过滤器的 2 行是来自XML 中ID第一个和第二个item节点的属性。流聚合返回四行,每个输入行一行,有效地将内连接转换为外连接。

这是 Stream Aggregate 在其他情况下也会做的事情,还是在进行 XML 查询时只是发生了一些奇怪的事情?

我在查询计划的 XML 版本中看不到任何提示,表明此 Stream Aggregate 的行为应该与我之前注意到的任何其他 Stream Aggregate 有所不同。

Pau*_*ite 13

聚合是标量聚合(没有 group by 子句)。这些在 SQL Server 中定义为始终生成一行,即使输入为空。

对于标量聚集体,MAX没有行的是NULLCOUNT没有行的是零,例如。优化器知道这一切,并且可以在合适的情况下将外连接转换为内连接。

-- NULL for a scalar aggregate
SELECT MAX(V.v) FROM (VALUES(1)) AS V (v) WHERE V.v = 2;

-- No row for a vector aggregate
SELECT MAX(V.v) FROM (VALUES(1)) AS V (v) WHERE V.v = 2 GROUP BY ();
Run Code Online (Sandbox Code Playgroud)

有关聚合的更多信息,请参阅我的文章《标量和向量聚合的乐趣》


Rob*_*ley 10

这里要记住的是,执行计划会吸收数据。

因此,嵌套循环运算符调用了 Stream Aggregate 4 次。Stream Aggregate 也调用了 Filter 4 次,但只获得了两次值。

所以流聚合给出了四个值。它两次给出一个值,两次给出 Null。