Назад | Перейти на главную страницу

SQL Server: почему требуется перекомпиляция хранимых процедур?

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

У меня есть приложение Windows Forms (.net 3.5), которое использует множество таблиц данных, и после выполнения этого скрипта время, необходимое для открытия тяжелой формы с данными, увеличилось с 8 до 4 секунд.

Нужно ли мне регулярно запускать такой скрипт? Я думал, что SQL Server позаботится о процедурах компиляции и тому подобном.


BTW: этот вопрос должен быть на SO? Я думал, что администраторы баз данных будут здесь, в SF.

Из Microsoft :

"Поскольку база данных изменяется такими действиями, как добавление индексов или изменение данных в индексированных столбцах, исходные планы запросов, используемые для доступа к ее таблицам, должны быть снова оптимизированы путем их повторной компиляции. Эта оптимизация происходит автоматически при первом запуске хранимой процедуры после того, как Microsoft SQL Server перезапускается. Это также происходит, если основная таблица, используемая хранимой процедурой, изменяется. Но если добавляется новый индекс, от которого может выиграть хранимая процедура, оптимизация не происходит до следующего запуска хранимой процедуры после Microsoft SQL. Сервер перезагружен. В этой ситуации может быть полезно принудительно перекомпилировать хранимую процедуру при следующем выполнении.

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

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

Это, кстати, не сильно отличается от того, что делают приложения .NET, если задуматься. Приложения .NET компилируются до промежуточного языкового состояния, но полностью компилируются по умолчанию только при первом запуске.

Когда SP компилируется, путь его выполнения фиксируется. Он не может использовать преимущества новых индексов или различных стратегий, основанных на размерах таблиц. Перекомпиляция позволяет повторно оценить условия выполнения.

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