이것은 SQL Server 2016의 버그입니까?
예. 확실히 이것은 올바른 행동이 아닙니다. 난 여기가보고 되고 SQL 서버 2016 SP2의 CU9에 고정 .
으로 미카엘 에릭손은 코멘트에 말했다 sys.database_scoped_configurations
과 sys.dm_exec_sessions
형식보기로 구현됩니다
SELECT ...
FROM OpenRowset(TABLE xxxx)
그러나 아래의 두 가지 계획을 비교하면 분명한 차이점이 있습니다.
DBCC TRACEON(3604);
DECLARE @database_scoped_configurations TABLE(x INT);
INSERT INTO @database_scoped_configurations
SELECT configuration_id
FROM sys.database_scoped_configurations
OPTION (QUERYTRACEON 8608, QUERYTRACEON 8615, QUERYTRACEON 8619, QUERYTRACEON 8620 );
DECLARE @dm_exec_sessions TABLE(x INT);
INSERT INTO @dm_exec_sessions
SELECT session_id
FROM sys.dm_exec_sessions
OPTION (QUERYTRACEON 8608, QUERYTRACEON 8615, QUERYTRACEON 8619, QUERYTRACEON 8620 );
이 두 쿼리에 대한 추적 플래그 8619 출력 결과
규칙 적용 : EnforceHPandAccCard-x0-> 스풀 또는 상단 (x0)
SQL Server는 TVF의 소스가 삽입 대상이 아니므로 할로윈 보호가 필요하다는 것을 분명히 알 수 없습니다.
세션의 경우 이것은 모든 행을 먼저 캡처하는 스풀로 구현되었습니다. 에서 database_scoped_configurations
를 추가하여 TOP 1
계획에. TOP
할로윈 보호 에 대한 사용법은 이 기사에서 설명 합니다. 또한이 문서에는 스풀이 TOP
예상대로 작동 하지 않고 강제로 스풀링하도록 문서화되지 않은 추적 플래그가 언급되어 있습니다.
DECLARE @database_scoped_configurations TABLE(x INT);
INSERT INTO @database_scoped_configurations
SELECT configuration_id
FROM sys.database_scoped_configurations
OPTION (QUERYTRACEON 8692)
TOP 1
스풀이 아닌 사용시 명백한 문제점 은 삽입 된 행 수를 임의로 제한한다는 것입니다. 따라서 이것은 함수가 리턴 한 행 수가 <= 1 인 경우에만 유효합니다.
초기 메모는 다음과 같습니다
이것을 쿼리 2의 초기 메모와 비교하십시오.
위의 내용을 올바르게 이해하면 첫 번째 TVF가 최대 한 행을 반환 할 수 있다고 생각하므로 잘못된 최적화가 적용됩니다. 두 번째 쿼리의 최대 값은 1.34078E+154
( 2^512
) 로 설정되어 있습니다.
이 최대 행 개수가 어디에서 파생되는지 전혀 모르겠습니다. 아마도 DMV 작성자가 제공 한 메타 데이터일까요? 할로윈 문제가 발생하지 않도록 막지 않기 때문에 TOP(50)
해결 방법을 다시 쓰지 않는 것도 이상합니다 (무한하게 계속 진행하지는 않지만)TOP(1)
TOP(50)