Comportamento aggregato flusso dispari


11

Query:

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

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

Risultato:

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

Progetto esecutivo:

inserisci qui la descrizione dell'immagine

Il ramo superiore distrugge l'XML su quattro righe e il ramo inferiore recupera il valore per l'attributo ID.

Ciò che mi sembra strano è il numero di righe restituite dall'operatore Stream Aggregate. Le 2 righe che provengono dal filtro sono l' IDattributo del primo e del secondo itemnodo nell'XML. Stream Aggregate restituisce quattro righe, una per ogni riga di input, trasformando efficacemente il Join interno in un Join esterno.

È qualcosa che Stream Aggregate fa anche in altre circostanze o è qualcosa di strano quando si fanno query XML?

Non riesco a vedere alcun suggerimento nella versione XML del piano di query secondo cui questo Stream Aggregate dovrebbe comportarsi in modo diverso rispetto a qualsiasi altro Stream Aggregate che ho notato prima.

Risposte:


13

L'aggregato è un aggregato scalare (nessuna clausola group by). Questi sono definiti in SQL Server per produrre sempre una riga, anche se l'input è vuoto.

Per un aggregato scalare , MAXnessuna riga è NULL, COUNTnessuna riga è zero, ad esempio. L'ottimizzatore sa tutto di questo e può trasformare un join esterno in un join interno in circostanze adeguate.

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

Per ulteriori informazioni sugli aggregati, vedere il mio articolo Fun With Scalar and Vector Aggregates .


10

La cosa da ricordare qui è che i piani di esecuzione assorbono i dati.

Quindi l'operatore Nested Loop chiama Stream Aggregate 4 volte. Stream Aggregate chiama anche il filtro 4 volte, ma ottiene un valore solo due volte.

Quindi Stream Aggregate fornisce quattro valori. Due volte dà un valore e due volte dà Null.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.