Odd Stream Aggregate-Verhalten

11

Abfrage:

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

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

Ergebnis:

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

Ausführungsplan:

Geben Sie hier die Bildbeschreibung ein

Der obere Zweig zerlegt das XML in vier Zeilen und der untere Zweig ruft den Wert für das Attribut ab ID.

Was mir seltsam erscheint, ist die Anzahl der vom Stream Aggregate-Operator zurückgegebenen Zeilen. Die 2 Zeilen, die vom Filter stammen, sind das IDAttribut vom ersten und zweiten itemKnoten im XML. Das Stream-Aggregat gibt vier Zeilen zurück, eine für jede Eingabezeile, wodurch die innere Verknüpfung effektiv in eine äußere Verknüpfung umgewandelt wird.

Ist dies etwas, was Stream Aggregate auch unter anderen Umständen tut, oder ist es nur etwas Seltsames, wenn XML-Abfragen ausgeführt werden?

Ich kann in der XML-Version des Abfrageplans keine Hinweise darauf sehen, dass sich dieses Stream-Aggregat anders verhalten sollte als jedes andere Stream-Aggregat, das ich zuvor bemerkt habe.

Mikael Eriksson
quelle

Antworten:

13

Das Aggregat ist ein skalares Aggregat (keine Group by-Klausel). Diese werden in SQL Server so definiert, dass immer eine Zeile erstellt wird, auch wenn die Eingabe leer ist.

Für ein skalares Aggregat ist beispielsweise MAXkeine Zeile NULL, COUNTkeine Zeile Null. Der Optimierer weiß alles darüber und kann unter geeigneten Umständen eine äußere Verbindung in eine innere Verbindung umwandeln.

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

Weitere Informationen zu Aggregaten finden Sie in meinem Artikel Spaß mit Skalar- und Vektoraggregaten .

Paul White 9
quelle
10

Hier ist zu beachten, dass Ausführungspläne die Daten durchziehen.

Der Operator für verschachtelte Schleifen ruft das Stream-Aggregat also viermal auf. Das Stream-Aggregat ruft den Filter ebenfalls viermal auf, erhält jedoch nur zweimal einen Wert.

Das Stream-Aggregat gibt also vier Werte an. Zweimal gibt es einen Wert und zweimal gibt es Null.

Rob Farley
quelle