복붙노트

[SQL] 쿼리 날짜 식 느린 실행되지만 빠른 문자열 리터럴로

SQL

쿼리 날짜 식 느린 실행되지만 빠른 문자열 리터럴로

나는 SQL Server 2008의 아래 조건에 쿼리를 실행하고 있습니다.

Where FK.DT = CAST(DATEADD(m, DATEDIFF(m, 0, getdate()), 0) as DATE)  

쿼리는 위의 조건과 실행 영원히 걸리지 만하면 그냥 말

Where FK.DT = '2013-05-01' 

그것은 2 분에 큰 실행됩니다. FK.DT의 키는 달의 데이터를 시작하는 값을 포함합니다.

어떤 도움을, 나는 왜 이런 일 단지 우둔입니다.

해결법

  1. ==============================

    1.이것은 더 일할 수 :

    이것은 더 일할 수 :

    Where FK.DT = cast(getdate() + 1 - datepart(day, getdate()) as date)
    

    추적 플래그 4199에서 실행하지 않는 카디널리티 추정에 영향을 미치는 버그가있다. 글을 쓰는 시점에서

    SELECT DATEADD(m, DATEDIFF(m, getdate(), 0), 0), 
           DATEADD(m, DATEDIFF(m, 0, getdate()), 0)
    

    보고

    +-------------------------+-------------------------+
    | 1786-06-01 00:00:00.000 | 2013-08-01 00:00:00.000 |
    +-------------------------+-------------------------+
    

    버그 카디널리티 추정치를 도출 할 때 문제의 술어가 두 번째가 아닌 첫 번째 날짜를 사용한다는 것입니다. 다음 설치를위한 그래서.

    CREATE TABLE FK
    (
    ID INT IDENTITY PRIMARY KEY,
    DT DATE,
    Filler CHAR(1000) NULL,
    UNIQUE (DT,ID)
    )
    
    INSERT INTO FK (DT)
    SELECT TOP (1000000) DATEADD(m, DATEDIFF(m, getdate(), 0), 0)
    FROM master..spt_values o1, master..spt_values o2
    UNION ALL
    SELECT               DATEADD(m, DATEDIFF(m, 0, getdate()), 0)
    
    SELECT COUNT(Filler)
    FROM FK
    WHERE FK.DT = CAST(DATEADD(m, DATEDIFF(m, 0, getdate()), 0) AS DATE)  
    

    견적은 일치하는 행의 수는 10 만명이 될 것입니다. 이 날짜 '1786년 6월 1일를'일치하는 번호입니다.

    그러나 다음과 같은 쿼리를 모두

    SELECT COUNT(Filler)
    FROM FK
    WHERE FK.DT = CAST(GETDATE() + 1 - DATEPART(DAY, GETDATE()) AS DATE)
    
    SELECT COUNT(Filler)
    FROM FK
    WHERE FK.DT = CAST(DATEADD(m, DATEDIFF(m, 0, getdate()), 0) AS DATE)  
    OPTION (QUERYTRACEON 4199)
    

    이 계획주세요

    훨씬 더 정확한 카디널리티 지금 계획을 추정 인해 단 하나의 인덱스 전체 스캔보다는 추구한다.

  2. ==============================

    2.대부분의 경우, 아래 아마 적용됩니다. 이 특정한 경우에,이 DATEDIFF를 포함하는 옵티 마이저 버그입니다. 여기와 여기에 대해 자세히 설명합니다. 죄송합니다에 대한 t-clausen.dk 의심했지만, 그의 대답은 간단 버그의 존재를 모른 채 직관적이고 논리적 인 해결책이 아니었다.

    대부분의 경우, 아래 아마 적용됩니다. 이 특정한 경우에,이 DATEDIFF를 포함하는 옵티 마이저 버그입니다. 여기와 여기에 대해 자세히 설명합니다. 죄송합니다에 대한 t-clausen.dk 의심했지만, 그의 대답은 간단 버그의 존재를 모른 채 직관적이고 논리적 인 해결책이 아니었다.

    여전히 악화 - - NVARCHAR - 그래서 DT 실제로 DATE하지 바보 VARCHAR 같은 또는 가정하고 먼저 실행되는 매우 다른 날짜 값을 사용하는 캐시 된 계획을 가지고 있기 때문에 이것은 아마도, 따라서 매우 다른 일반적인 데이터에 계획 취사 선택 분포. 당신이 이것을 극복 할 수있는 방법이 있습니다 :

  3. from https://stackoverflow.com/questions/18241977/query-runs-slow-with-date-expression-but-fast-with-string-literal by cc-by-sa and MIT license