奇数ストリームの集計動作


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を4行に細断し、下のブランチは属性の値をフェッチしますID

奇妙に感じるのは、Stream Aggregateオペレーターから返される行の数です。Filterからの2つの行は、XMLのID最初と2番目のitemノードの属性です。Stream Aggregateは、各入力行に1つずつ、4つの行を返し、内部結合を外部結合に効果的に変換します。

これは、Stream Aggregateが他の状況でも行うことですか、それともXMLクエリを実行するときに奇妙なことですか?

XMLバージョンのクエリプランで、このStream Aggregateの動作が以前に気付いた他のどのStream Aggregateとも異なるはずであるというヒントはありません。

回答:


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

集計の詳細については、私の記事「Fun With Scalar and Vector Aggregates」を参照してください。


10

ここで覚えておくべきことは、実行計画はデータを吸い込むということです。

したがって、Nested LoopオペレーターはStream Aggregateを4回呼び出します。Stream AggregateもFilterを4回呼び出しますが、値を2回しか取得しません。

したがって、Stream Aggregateは4つの値を提供します。2倍は値を与え、2倍はNullを与えます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.