Планы выполнения хороши, но иногда они просто не говорят вам правду. Итак, вот доказательство, основанное на тесте производительности.
(и нижняя строка - выражение не оценивается для каждой строки)
;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()
.