奇数流聚合行为


11

查询:

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

select I.X.value('@ID', 'int')
from @X.nodes('/item') as I(X);

结果:

-----------
0
1
NULL
NULL

执行计划:

在此处输入图片说明

顶部分支将XML切成四行,底部分支获取该属性的值ID

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

这是否也是Stream Aggregate在其他情况下所做的事情,还是在进行XML查询时发生的奇怪事情?

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

Answers:


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 ();

有关聚合的更多信息,请参见我的文章“ 与标量和矢量聚合一起玩”


10

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

因此,嵌套循环运算符会调用Stream Aggregate 4次。流聚合也调用过滤器4次,但仅获得两次值。

因此,“流聚合”给出了四个值。两次给出一个值,两次给出Null。

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.