내 인덱스를 찾는 것이 올바른 행 수를 추정 할 수 있는데 정렬 연산자가 할 수없는 이유는 무엇입니까?


11

조건 자에서 함수를 사용하는 쿼리는 다음과 같습니다.

commentType = 'EL'
AND commentDateTime >= DATEADD(month,datediff(month,0,getdate()) - 13,0)

40K 행이있는 commentType에 필터링 된 인덱스가 있으며 쿼리를 실행할 때 인덱스 검색의 예상 행 수는 매우 정확하지만 (약 11K) 다음 단계 (정렬 연산자)의 경우 통계를 완전히 무시하고 필터링 된 인덱스의 총 행 수를 추정합니다.

왜 이런 일이 발생합니까? sargability 에 대한 기본 사항을 알고 있으며 dateadd를 실제 날짜 (2014-01-01) 및 voila로 대체하여 온전함을 위해 테스트했습니다 ... 정렬은 행 수를 올바르게 추측하기 시작했습니다 ...

왜 이런 일이 발생하며 어떻게 해결할 수 있습니까? 고정 날짜를 전달할 수 없습니다 ...


DATEADD(month,datediff(month,0,getdate()) - 13,0)이해가되지 않습니다. 이것으로 무엇을하려고합니까? 개선 / 간단 화 될 수 있습니까?
Daniel Hutmacher

2
@Daniel 13 개월 전의 시작입니다.
Aaron Bertrand

1
또한 사용중인 SQL Server 버전 (?)을 반영하도록 질문을 편집하십시오. 태그를 사용하십시오.
Daniel Hutmacher

DATEADD(month, -13, DATEADD(day, 1-DATEPART(day, SYSDATETIME()))차이가 있는지 확인해 볼 수 있습니까?
Daniel Hutmacher

에 필터링되지 않은 인덱스 (commentType, commentDate)가 있으면 더 잘 작동합니까? 필터링 된 인덱스가 계획의 여러 지점에서 추정치를 잘못보고하는 경우가 있습니다. 필터링 된 인덱스의 총 수를보고하면 예상치 못한 것으로 보이지만 실제로 계획이 잘못 표시되고있는 것입니다.
Rob Farley

답변:


9

두 개의 DATEDIFF 인수를 바꾸는 추정기 버그로 인해 추정치가 잘못되었다고 생각합니다. 나는 이것에 대해 여기에서 이야기합니다 :

해결 방법은 DATEDIFF (2008+)를 사용하지 않고 13 개월 전의 첫 날을 계산하는 것입니다.

DATEADD(MONTH, -13, DATEADD(DAY, 1-DATEPART(DAY,GETDATE()), CONVERT(DATE, GETDATE()));

나는 견적을 처리 할 긍정적 이지 않다 (필터링 된 인덱스로 테스트하지 않았으며, 실제로 정렬이 무엇을하는지 또는 왜 계획 및 / 또는 나머지 쿼리없이 다른 견적이 있는지 확실하지 않습니다. ).

Microsoft가 권장하는 수정 사항은 TF 4199를 사용하는 것이지만 여기서해야 할 것이 확실하지 않습니다.

또 다른 옵션은 사용중인 모든 SQL Server 버전에 대해 절대 최신 SP / CU를 사용하고 있는지 확인하는 것입니다. 다음 KB 기사에서 수정되었으므로 여전히 TF 4199를 사용해야합니다. 2014 이상인 경우를 제외하고) :

수정 사항은 다음 빌드로 얻을 수 있습니다.

(다음에는 SELECT @@VERSION질문에 결과를 포함 시키 십시오.)

KB 기사에 따르면 DATEDIFF는 행 수를 과소 평가할 수 있으며 이는 시나리오에서 발생하는 것과 반대입니다. 그렇다고 픽스가 적용되지 않는 것은 아닙니다. 데이터와보고있는 범위에 따라 추정치가 어느 쪽이든 갈 수 있기 때문에 KB 기사 문구가 정확하지 않다고 생각합니다.

위의 블로그 게시물에서 2014 년부터는 교체가 더 이상 발생하지 않음을 확인했습니다. 안전하기 위해 아마 당신의 술어에서 DATEDIFF를 긁어 내고 다른 방법을 사용하여 범위의 시작을 계산할 것입니다. 과도한 스왑을 방지하기 위해 4199의 오버 킬이나 동적 SQL을 사용하지 않는 것이 좋습니다.


도와 주셔서 감사합니다 ! 나는 당신의 제안을 시도하고 계획이 변경되었습니다. 이것은 이전의 방법입니다 : s16.postimg.org/t5j6o1yed/fix_wrong.png 이것은 내가 당신의 datediff를 변경 한 후의 방법입니다 : postimg.org/image/5f725rj83 나는 당신이 나에게 준 모든 URL을 읽을 것입니다 . 건배.
MrKudz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.