Задать вопрос
@zhaar

Почему запрос отрабатывает дольше при использования переменных?

Есть сложный запрос к большому количеству данных, который заливается в таблицу в уже обобщенном виде из нескольких десятков тысяч строк при 7 столбцах.
При отладке запроса в условии, где требуется указать дату я явно указывал период [date00] between '20190101' and '20190401', запускал выполнение скрипта и он примерно за две с половиной минуты отрабатывал.

Но когда я перешел на использование переменных, то время выполнения запроса непонятно возросло

declare @today date = '20190101'
declare @year datetime = (select cast(datename(yyyy, @today) as datetime))
declare @quarter int = datepart(quarter,@today)
declare @qbegin datetime = dateadd(QUARTER,@quarter-1,@year)
declare @qend datetime = dateadd(ss,-1,(dateadd(QUARTER,@quarter,@year)))
select @today,@year,@quarter,@qbegin,@qend
...
...and date00 between  @qbegin and @qend--

Колонка [date00], по которой происходит фильтрация имеет формат datetime
Сначала думал, что может быть скрипт отрабатывает долго из-за первоначального расхождения в форматах данных (одна из переменных была просто date), но нет, привел все к единому виду, но запрос отрабатывает дольше, чем при явном указании дат. Почему?

Да, есть вариант обхода этой проблемы в использовании динамического sql, но все же непонятно, почему переменные так влияют на время выполнения скрипта.
  • Вопрос задан
  • 720 просмотров
Подписаться 1 Средний 7 комментариев
Решения вопроса 1
tsklab
@tsklab Куратор тега SQL Server
Здесь отвечаю на вопросы.
Найдено в сети:
Когда вы используете константу, значение известно оптимизатору, поэтому может определять селективность (и возможное использование индекса) на основе этого. Когда вы используете переменную, значение неизвестно оптимизатору.

Performance Impact: Constant value -vs- Variable.

похоже вариантов решения немного...
запрос начнет отрабатывать без старых кэшированных данных
Личный опыт: при освоении MS SQL, обратил внимание, что промежуточный слой ADO, иногда меняет в реальном запросе константы на переменные и наоборот. При использовании хранимых процедур план запроса строится и кэшируется при её создании. Это одна из причин оборачивать в процедуру запрос даже без дополнительных обработок.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@zhaar Автор вопроса
Для тех, кому лень читать, решение - в конец тяжелого запроса добавить строку
OPTION(recompile)

И запрос начнет отрабатывать без старых кэшированных данных. Мир, труд. май.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы