Функции SQL Server, которые считаются константами времени выполнения , оцениваются только один раз.GETDATE()
является такой функцией, а DATEADD(..., constant, GETDATE())
также является константой времени выполнения.Оставляя фактический вызов функции внутри запроса, вы позволяете оптимизатору увидеть, какое значение будет фактически использоваться (в отличие от сниффинга значения переменной), а затем он может соответствующим образом скорректировать свои оценки мощности, возможно, придумав лучший план.
Также прочтите это: Устранение неполадок при низкой производительности запросов: сворачивание констант и оценка выражений во время оценки мощности .
@ Martin Smith
Вы можетевыполните этот запрос:
set nocount on;
declare @known int;
select @known = count(*) from sysobjects;
declare @cnt int = @known;
while @cnt = @known
select @cnt = count(*) from sysobjects where getdate()=getdate()
select @cnt, @known;
В моем случае через 22 секунды он достиг граничного случая и цикл завершился.Важно, что цикл завершился с @cnt
ноль .Можно было бы ожидать, что если getdate()
вычисляется для каждой строки, то мы получим @cnt, отличный от правильного числа @known, но не 0. Тот факт, что @cnt равен нулю, когда цикл существует, показывает, что каждый getdate()
был оцененодин раз, а затем одно и то же постоянное значение использовалось для каждой строки, ГДЕ фильтрующейся (не совпадающей).Мне известно, что один положительный пример не доказывает теорему, но я думаю, что дело достаточно убедительное.