홀수 스트림 집계 동작 Aggregate 연산자에서

질문:

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 연산자에서 반환 된 행 수입니다. 필터에서 나오는 2 개의 행 은 XML ID의 첫 번째 item노드 와 두 번째 노드 의 속성입니다 . 스트림 집계는 입력 행마다 하나씩 4 개의 행을 반환하여 내부 조인을 외부 조인으로 효과적으로 전환합니다.

이것이 Stream Aggregate가 다른 상황에서도 수행하는 것입니까, 아니면 XML 쿼리를 수행 할 때 이상한 일입니까?

XML 버전의 쿼리 계획에서이 Stream Aggregate가 이전에 주목 한 다른 Stream Aggregate와 다르게 동작해야한다는 힌트를 볼 수 없습니다.



답변

집계는 스칼라 집계입니다 (그룹 별 절 없음). 입력이 비어 있어도 항상 행을 생성하도록 SQL Server에 정의됩니다.

A의 스칼라 집계, MAX이다없는 행으로 NULL, COUNT어떤 행의 예를 들면, 제로이다. 옵티마이 저는이 모든 것을 알고 있으며 적절한 상황에서 외부 조인을 내부 조인으로 변환 할 수 있습니다.

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

집계에 대한 자세한 내용은 내 기사 Scalar 및 Vector Aggregates를 참조하십시오 .


답변

여기서 기억해야 할 것은 실행 계획이 데이터를 빨아 들인다는 것입니다.

따라서 Nested Loop 연산자는 Stream Aggregate를 4 번 호출합니다. 스트림 집계는 필터를 4 번 호출하지만 값은 두 번만 가져옵니다.

따라서 스트림 집계는 네 가지 값을 제공합니다. 두 번 값을 제공하고 두 번 Null을 제공합니다.