답변:
런타임 상수 로 알려진 특정 함수는 상수 접기 라는 프로세스를 거칩니다 . 상수를 '폴딩'하면 쿼리 실행 초기에 표현식이 평가되고 결과는 캐시되고 필요한 경우 캐시 된 결과가 대신 캐시됩니다. 쿼리의 표현은 DATEADD(dd, 0, DATEDIFF(dd, 0, getdate()))
런타임 상수이므로 afaik은 쿼리 당 한 번만 접 히고 평가됩니다.
사소한 RAND()
일로 : 접을 수 없을 것으로 예상 되는 기능은 실제로 접을 수 있으므로 예기치 않은 동작이 발생합니다. 그러나 다른 예를 들어 NEWID()
접을 수 없으며 행마다 평가를 수행합니다.
실행 계획은 훌륭하지만 때로는 진실을 말하지 않습니다. 여기 성능 테스트를 기반으로 한 증명이 있습니다.
(그리고 결론-모든 행에 대해 표현식이 평가되는 것은 아닙니다)
;with t(i) as (select 0 union all select i+1 from t where i < 9)
select getdate()-1 as col1,getdate() as col2,getdate() as col3
into #t
from t t0,t t1,t t2,t t3,t t4,t t5,t t6,t t7
(100000000 개의 행이 영향을 받음)
이것은 OP 쿼리이며 실행하는 데 약 12 초가 걸립니다.
SELECT col1
FROM #t
WHERE
DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
BETWEEN col2
AND col3
;
실행 전에 매개 변수에 날짜를 저장하는이 쿼리는 12 초 정도의 시간이 걸립니다.
declare @dt datetime = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
SELECT col1
FROM #t
WHERE
@dt
BETWEEN col2
AND col3
;
그리고 결과를 확인하기 위해
-col1에서 계산을 수행하므로 모든 행의 표현식을 다시 계산 해야하는이 쿼리는 실행하는 데 약 30 초가 걸립니다.
SELECT col1
FROM #t
WHERE
DATEADD(dd, 0, DATEDIFF(dd, 0, col1))
BETWEEN col2
AND col3
;
동일한 쿼리에 대해 모든 쿼리가 반복적으로 실행되었습니다.
GETDATE()
.