이 스트림 집계가 필요한 이유는 무엇입니까?


12

이 쿼리를 확인하십시오. 매우 간단합니다 (테이블 및 인덱스 정의 및 repro 스크립트에 대해서는 게시물 끝 참조).

SELECT MAX(Revision)
FROM dbo.TheOneders
WHERE Id = 1 AND 1 = (SELECT 1);

참고 : "AND 1 = (SELECT 1) 은이 쿼리가 자동 매개 변수화되지 않도록하는 것입니다.

그리고 계획은 다음과 같습니다 ( 계획 링크를 붙여 넣으십시오) .

스트림 agg와 계획

거기에 "상위 1"이 있기 때문에 스트림 집계 연산자를보고 놀랐습니다. 하나의 행만 보장되므로 나에게는 필요하지 않은 것 같습니다.

이 이론을 테스트하기 위해 논리적으로 동등한 쿼리를 시도했습니다.

SELECT MAX(Revision)
FROM dbo.TheOneders
WHERE Id = 1
GROUP BY Id;

그 계획은 다음과 같습니다 ( 계획 링크 붙여 넣기 ).

스트림 어그없이 계획

물론 계획 별 그룹은 스트림 집계 연산자 없이도 얻을 수 있습니다.

두 쿼리 모두 인덱스 끝에서 "뒤로"를 읽고 최대 수정을 얻기 위해 "상위 1"을 수행합니다.

내가 여기서 무엇을 놓치고 있습니까? 스트림 집계가 실제로 첫 번째 쿼리에서 작업을 수행합니까, 아니면 제거 할 수 있어야합니까 (그리고 최적화 프로그램이 제한하지 않는 제한 사항입니까)?

그건 그렇고, 이것은 이것이 실제로 실용적인 문제가 아니라는 것을 알고 있습니다 (질문은 CPU의 0ms와 경과 시간을보고합니다), 나는 여기에 전시되는 내부 / 행동에 대해 궁금합니다.


위의 두 쿼리를 실행하기 전에 실행 한 설정 코드는 다음과 같습니다.

DROP TABLE IF EXISTS dbo.TheOneders;
GO

CREATE TABLE dbo.TheOneders
(
    Id INT NOT NULL,
    Revision SMALLINT NOT NULL,
    Something NVARCHAR(23),

    CONSTRAINT PK_TheOneders PRIMARY KEY NONCLUSTERED (Id, Revision)
);
GO

INSERT INTO dbo.TheOneders
    (Id, Revision, Something)
SELECT DISTINCT TOP 1000 
    1, m.message_id, 'Do...'
FROM sys.messages m
ORDER BY m.message_id
OPTION (MAXDOP 1);

INSERT INTO dbo.TheOneders
    (Id, Revision, Something)
SELECT DISTINCT TOP 100 
    2, m.message_id, 'Do that thing you do...'
FROM sys.messages m
ORDER BY m.message_id
OPTION (MAXDOP 1);
GO

답변:


16

WHERE절 과 일치하는 행이 없으면이 집계의 역할을 볼 수 있습니다 .

SELECT MAX(Revision)
FROM   dbo.TheOneders
WHERE  Id = 1
       AND 1 = 1 /*To avoid auto parameterisation*/
       AND Id%3 = 4  /*always false*/

이 경우 0 행이 집계에 들어가지만 NULL이 경우 올바른 의미가 반환되므로 여전히 1 행을 방출 합니다.

여기에 이미지 설명을 입력하십시오

이것은 벡터와 반대로 스칼라 집계입니다.

"논리적으로 동등한"쿼리는 동일하지 않습니다. 추가 GROUP BY Id하면 벡터 집계가되고 올바른 동작은 행을 반환하지 않는 것입니다.

이에 대한 자세한 내용 은 스칼라 및 벡터 집계통한 재미를 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.