У меня есть два почти идентичных запроса на одном экземпляре SQL Server 2005:
- Первый - это оригинальный
SELECT
запрос, сгенерированный LINQ (я знаю, я знаю ... я не разработчик приложений, просто администратор БД :). - Второй точно такой же, как первый, добавленный
OPTION (RECOMPILE)
в конце.
Больше ничего не изменилось.
Первый занимает 55 секунд при каждом запуске.
Второй занимает 2 секунды.
Оба набора результатов идентичны.
Почему этот намек привел к такому значительному увеличению производительности?
В разделе «Книги онлайн» RECOMPILE
не содержится подробного объяснения:
Указывает ядру СУБД SQL Server отказаться от плана, сгенерированного для запроса после его выполнения, заставляя оптимизатор запросов перекомпилировать план запроса при следующем выполнении того же запроса. Без указания RECOMPILE компонент Database Engine кэширует планы запросов и использует их повторно. При компиляции планов запросов подсказка запроса RECOMPILE использует текущие значения любых локальных переменных в запросе и, если запрос находится внутри хранимой процедуры, текущие значения передаются любым параметрам.
RECOMPILE - полезная альтернатива созданию хранимой процедуры, которая использует предложение WITH RECOMPILE, когда необходимо перекомпилировать только подмножество запросов внутри хранимой процедуры, а не всю хранимую процедуру. Для получения дополнительной информации см. Перекомпиляция хранимых процедур. RECOMPILE также полезен при создании руководств плана. Для получения дополнительной информации см. Оптимизация запросов в развернутых приложениях с помощью руководств по планированию.
Поскольку в моем запросе много локальных переменных, я предполагаю, что SQL Server способен (серьезно) оптимизировать его, когда я использую OPTION (RECOMPILE)
подсказку запроса.
Куда бы я ни посмотрел, люди говорят, что этого OPTION (RECOMPILE)
следует избегать. Объяснение этому обычно заключается в том, что при использовании этой подсказки SQL Server не может повторно использовать этот план исключения и, следовательно, каждый раз приходится тратить время на его перекомпиляцию.
(Но) Учитывая гигантское преимущество в производительности, я склонен думать, что использование этого подсказки для запроса на этот раз было бы хорошо.
Должен ли я использовать это? Если нет, то есть ли способ заставить SQL Server использовать лучший план выполнения без этой подсказки и без изменения приложения?