Мне было предложено, чтобы использование операторов 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
где невозможно заранее определить, какая ветвь будет выполнена?
sql-server
sql-server-2008
sql-server-2005
query-performance
AnthonyWJones
источник
источник
Ответы:
SQL Server оптимизирует процесс компиляции плана запроса для хранимой процедуры, игнорируя условные ветви внутри хранимой процедуры. План будет сгенерирован на основе параметров, использованных для первого выполнения, это вызовет проблемы, если параметры отличаются для филиалов.
Я бы поместил SQL для каждой из ветвей в их собственную хранимую процедуру, чтобы сгенерированный план основывался на фактическом использовании параметров для этой ветки.
источник
Единственный ярлык будет
IF 1 = 1
И @parameter, и EXISTS все еще требуют обработки для «общего случая» (
@parameter = 42
скажем)Сказав это ... что говорит реальный план выполнения, а также профилировщик, фиксирующий события перекомпиляции? (Мне не нравятся оценочные планы согласно ответу Джао)
источник
Попробуйте отобразить примерный план выполнения, а не фактический. Вы увидите, что первый содержит
COND
оператор.Этот оператор был также включен в кешированный план выполнения. В вашем примере примерный план выплат будет содержать один оператор COND и 2 ветки SELECT и, следовательно, будет полностью использоваться повторно. Потому что при выполнении пакетного SQL Server оценивает не только операторы DML, но и все остальные, получая их из плана.
Внутренне план выполнения - это структура, похожая на дерево выражений.
источник
Планы будут создаваться на основе переданных параметров, поэтому в действительности я бы сказал, что нет - наличие условной логики, которая обычно основана на параметрах, не наносит ущерба производительности.
Вы получите несколько планов, предполагая, что параметры вызывают достаточно различий, чтобы оптимизатор запросов мог их заметить.
Вы можете увидеть, что, включив Показать план выполнения, запустив сценарии - обратите внимание на различия в плане. Когда вы запустите процедуры (я предполагаю, что хранимые процедуры здесь), вы заметите, что первый раз, как правило, быстрее, второй удар использует сохраненный план. Измените параметры и повторите, затем запустите исходные параметры - теоретически план все еще будет в кеше, но это зависит от использования сервера (тики кеша - они не остаются навсегда ...) и т. Д.
источник
Может быть, он был улучшен в 2005 и 2008 годах, но использование условных выражений в 2000 году, скорее всего, будет хуже, чем вы описали, он скомпилирует план для наилучшей обработки первого запуска процедуры, а затем использует этот план для выполнения процедуры, даже когда условия изменилось. По моему опыту, это вызвало запросы, которые запускались в считанные минуты, чтобы работать в часах. Хотя сейчас я использую 2008 и использую 2005, я не могу комментировать, как там работают coditionals, так как я больше не использую их.
источник