Использование IF в T-SQL ослабляет или нарушает кэширование плана выполнения?


20

Мне было предложено, чтобы использование операторов IF в пакетах t-SQL отрицательно сказывалось на производительности. Я пытаюсь найти подтверждение или подтвердить это утверждение. Я использую SQL Server 2005 и 2008.

Утверждение таково со следующей партией:

IF @parameter = 0
 BEGIN
  SELECT ... something
 END

ELSE
 BEGIN
  SELECT ... something else
 END

SQL Server не может повторно использовать сгенерированный план выполнения, поскольку для следующего выполнения может потребоваться другая ветвь. Это подразумевает, что SQL Server полностью исключит одну ветвь из плана выполнения на том основании, что для текущего выполнения он уже может определить, какая ветвь необходима. Это правда?

Кроме того, что происходит в этом случае:

IF EXISTS (SELECT ....)
 BEGIN
  SELECT ... something
 END

ELSE
 BEGIN
  SELECT ... something else
 END

где невозможно заранее определить, какая ветвь будет выполнена?



1
SQL Server может и действительно использует план выполнения, поскольку он не учитывает ветви, а только операторы, содержащиеся в ветвях.
MartinC

Ответы:


10

SQL Server оптимизирует процесс компиляции плана запроса для хранимой процедуры, игнорируя условные ветви внутри хранимой процедуры. План будет сгенерирован на основе параметров, использованных для первого выполнения, это вызовет проблемы, если параметры отличаются для филиалов.

Я бы поместил SQL для каждой из ветвей в их собственную хранимую процедуру, чтобы сгенерированный план основывался на фактическом использовании параметров для этой ветки.


6

Единственный ярлык будет IF 1 = 1

И @parameter, и EXISTS все еще требуют обработки для «общего случая» ( @parameter = 42скажем)

Сказав это ... что говорит реальный план выполнения, а также профилировщик, фиксирующий события перекомпиляции? (Мне не нравятся оценочные планы согласно ответу Джао)


3

Попробуйте отобразить примерный план выполнения, а не фактический. Вы увидите, что первый содержит CONDоператор.

Этот оператор был также включен в кешированный план выполнения. В вашем примере примерный план выплат будет содержать один оператор COND и 2 ветки SELECT и, следовательно, будет полностью использоваться повторно. Потому что при выполнении пакетного SQL Server оценивает не только операторы DML, но и все остальные, получая их из плана.

Внутренне план выполнения - это структура, похожая на дерево выражений.


0

Планы будут создаваться на основе переданных параметров, поэтому в действительности я бы сказал, что нет - наличие условной логики, которая обычно основана на параметрах, не наносит ущерба производительности.

Вы получите несколько планов, предполагая, что параметры вызывают достаточно различий, чтобы оптимизатор запросов мог их заметить.

Вы можете увидеть, что, включив Показать план выполнения, запустив сценарии - обратите внимание на различия в плане. Когда вы запустите процедуры (я предполагаю, что хранимые процедуры здесь), вы заметите, что первый раз, как правило, быстрее, второй удар использует сохраненный план. Измените параметры и повторите, затем запустите исходные параметры - теоретически план все еще будет в кеше, но это зависит от использования сервера (тики кеша - они не остаются навсегда ...) и т. Д.


0

Может быть, он был улучшен в 2005 и 2008 годах, но использование условных выражений в 2000 году, скорее всего, будет хуже, чем вы описали, он скомпилирует план для наилучшей обработки первого запуска процедуры, а затем использует этот план для выполнения процедуры, даже когда условия изменилось. По моему опыту, это вызвало запросы, которые запускались в считанные минуты, чтобы работать в часах. Хотя сейчас я использую 2008 и использую 2005, я не могу комментировать, как там работают coditionals, так как я больше не использую их.


2
2005+ имеет перекомпиляцию на уровне выписки, так что у вас больше нет «одного плана на sp»
gbn
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.