이 쿼리를 확인하십시오. 매우 간단합니다 (테이블 및 인덱스 정의 및 repro 스크립트에 대해서는 게시물 끝 참조).
SELECT MAX(Revision)
FROM dbo.TheOneders
WHERE Id = 1 AND 1 = (SELECT 1);
참고 : "AND 1 = (SELECT 1) 은이 쿼리가 자동 매개 변수화되지 않도록하는 것입니다.
그리고 계획은 다음과 같습니다 ( 계획 링크를 붙여 넣으십시오) .
거기에 "상위 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