Какие факторы могут вызвать перекомпиляцию хранимых процедур на SQL Server?

какие факторы я должен знать, которые могут вызвать чрезмерную перекомпиляцию хранимых процедур?

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

динамический SQL и переменные пути, приводящие к различным выходам (по типу данных и/или количеству столбцов), похоже, что они могут представлять проблему. Верны ли предположения? Являются есть и другие примеры.

Edit: я нашел другой пример. Создание временной таблицы в операторе управления потоком приведет к перекомпиляции.

2 ответов


существует несколько способов обеспечить перекомпиляцию хранимой процедуры:

  • используя WITH RECOMPILE,
  • сделать хранимую процедуру динамический (думаю exec())
  • маркировка proc для перекомпиляции с sp_recompile.
  • изменение схемы, на которую опирается кэшированный план запроса
  • вызов DBCC FREEPROCCACHE
  • на уровне запроса отдельная инструкция в proc может быть перекомпилирована с подсказкой перекомпилировать запрос (SQL 2008).

факторы перекомпиляции

помимо перечисленных выше жестких факторов, что вызывает перекомпиляцию хранимых процедур? Ну, много чего. Некоторые из них переплетены со списком выше, но я хочу представить их b/c, это может быть не очевидно.

  • вставка или удаление большого количества данных (плотность данных в индексах и таблицах часто контролирует планы запросов)
  • перестроение индексов (изменение базового объекты)
  • создание / удаление временных таблиц (опять же, основные изменения DML).
  • план запроса стареет (думаю, не используется в последнее время, и sql хочет очистить использование памяти)

это отнюдь не исчерпывающий список. Оптимизатор запросов развивается и удивляет независимо от того, как долго вы используете SQL Server. Но вот некоторые ресурсы, которые можно использовать:

НО ПОДОЖДИТЕ-ЭТО ЕЩЕ НЕ ВСЕ !

С учетом сказанного, предположение в вашем вопросе заключается в том, что перекомпиляция всегда плохо сказывается на производительности. На самом деле, часто recompliation хорошо.

Итак, когда вы хотите его перекомпилировать? Давайте рассмотрим один пример proc, который ищет по фамилии. Хранимые процедуры делать 'нюхают параметрZebr% для zerbrowski. Индекс фамилии понимает, что это очень специфично и вернет, скажем, 3 строки из миллиона-поэтому строится один план выполнения. С proc, скомпилированным для низкой строки результат, следующий поиск для S%. Ну, S - ваше самое распространенное имя и соответствует 93,543 строкам из 1 миллиона.


некоторые параметры набора могут вызвать перекомпиляцию хранимых процедур или даже несколько перекомпиляций за одно выполнение!

некоторые из этих параметров могут быть даже не внутри SP

--this will cause recompilation
SET concat_null_yields_null ON;
EXEC spMyProc;

некоторые из параметров, которые вызывают перекомпиляцию, когда внутри SP:

параметр arithabort

параметр ansi_nulls

значение параметра

к счастью, это не вызывает перекомпиляцию: установите NOCOUNT на;