유출을 tempdb로 정렬하지만 예상 행은 실제 행과 같습니다.


14

최대 메모리가 25GB로 설정된 SQL Server 2016 SP2에는 분당 약 80 회 실행되는 쿼리가 있습니다. 쿼리는 약 4000 페이지를 tempdb에 흘립니다. 이로 인해 tempdb 디스크에 많은 IO가 발생합니다.

당신이 한 번 봐 걸릴 때 쿼리 계획을 (간체 쿼리)는 추정 된 행의 수는 실제 행의 수와 동일한 것으로 볼 수 있지만 여전히 발생 유출 것이다. 따라서 오래된 통계는 문제의 원인이 될 수 없습니다.

Tempdb에 대한 테스트 및 다음 쿼리 유출을 수행했습니다.

select id --uniqueidentifier
from SortProblem
where [status] ='A'
order by SequenceNumber asc
option (maxdop 1)

그러나 다른 열을 선택하면 유출이 발생하지 않습니다.

select startdate --datetime
from SortProblem
where [status] ='A'
order by SequenceNumber asc 
option (maxdop 1)

그래서 id 열의 크기를 '확대'하려고했습니다.

select CONVERT(nvarchar(512),id)
from SortProblem
where [status] ='A'
order by SequenceNumber asc 
option (maxdop 1)

그런 다음 유출이 발생하지 않습니다.

uniqueidentifier가 tempdb로 유출되는 이유는 무엇입니까? 약 20000 개의 레코드를 삭제하면 id 열을 선택할 때 유출이 발생하지 않습니다.

다음 스크립트를 사용하면 문제를 재현 할 수 있습니다.

CREATE TABLE SortProblem
  (
     id             UNIQUEIDENTIFIER,
     startdate      DATETIME,
     sequencenumber BIGINT,
     status         VARCHAR(50),
     PRIMARY KEY CLUSTERED(id)
  )

SET nocount ON;

WITH nums(num)
     AS (SELECT TOP 103000 ROW_NUMBER()
                             OVER (
                               ORDER BY 1/0)
         FROM   sys.all_objects o1,
                sys.all_objects o2)
INSERT INTO SortProblem
SELECT newid(),
       DATEADD(millisecond, num, GETDATE()),
       num,
       CASE
         WHEN num <= 100000 THEN 'A'
         WHEN num <= 101000 THEN 'B'
         WHEN num <= 102000 THEN 'C'
         WHEN num <= 103000 THEN 'D'
       END
FROM   nums

CREATE NONCLUSTERED INDEX [IX_Status]
  ON [dbo].[SortProblem]([status] ASC)
  INCLUDE ([sequencenumber]) 

답변:


14

추적 플래그 7470을 사용하십시오.

FIX : 예상 행 수와 행 크기가 올바른 경우 SQL Server 2012 또는 SQL Server 2014에서 정렬 연산자가 tempdb로 유출 됨

쿼리 계획 질문 에 대한 답변으로 썼습니다 :

이 추적 플래그는 계산에서 감독을 수정합니다. 사용하는 것이 안전하며 제 생각에는 기본적으로 켜져 있어야합니다. 예기치 않은 계획 변경을 피하기 위해 추적 플래그로 변경을 보호합니다.

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