Обычные подозреваемые:
- константы в adhoc, параметры в коде
- несоответствие типов данных в коде
- сниффинг параметров
Точка 1: оптимизатор может выбрать лучший план для констант.
Изменить константы = изменить план. Параметризованный плен можно восстановить
Точка 2 вводит неявные преобразования из-за приоритета типа данных,
например столбец varchar по сравнению с параметром nvarchar
Точка 3: используйте маскировку параметров или OPTIMIZE FOR UNKNOWN.
Редактирование: Для проверки: запустите сохраненный процесс, запустите sp_updatestats, запустите снова. Это сделает недействительными кэшированные планы, что лучше, чем очистка кэша планов
Изменить: после комментария jcolebrand
Вы можете отключить сниффинг несколькими способами. Основными 3 являются
- RECOMPILE. Это глупое ИМО.
- ОПТИМИЗИРУЙТЕ (так) НЕИЗВЕСТНО
- Маскировка параметров
Маскировка параметров:
DECLARE @MaskedParam varchar(10)
SELECT @MaskedParam = @SignaureParam
SELECT...WHERE column = @MaskedParam
Маскировка и подсказка ОПТИМИЗАЦИЯ имеют одинаковый эффект (возможно, по разным причинам). То есть оптимизатор должен использовать статистику и распределение данных ( Примечание: все еще тестируется Марком Стори-Смитом ), чтобы оценить параметры по их собственным достоинствам ? , а не то, что они были в последний раз. Оптимизатор может перекомпилировать или нет. В SQL Server 2005 добавлена перекомпиляция на уровне операторов, чтобы уменьшить влияние
Теперь, почему план с «вынюхиваемыми» параметрами является «липким» по сравнению с замаскированными / «неизвестными» параметрами, я не уверен.
Я использовал маскирование параметров начиная с SQL Server 2000 для всего, кроме самого простого кода. Я заметил, что это может произойти с более сложным кодом. А на моей старой работе у меня есть несколько процедур отчетов, которые я могу изменить по умолчанию для параметров плана. Я считаю, что подход "культа груза" был проще, чем звонок в службу поддержки.
Изменить 2, 12 октября 2011, после некоторого чата
Насколько я могу судить, маскирование параметров и ОПТИМИЗАЦИЯ ДЛЯ НЕИЗВЕСТНО имеют тот же эффект
. Подсказка более чистая, чем маскировка, но была добавлена в SQL Server 2008.
Обнаружение параметров происходит во время компиляции.
С RECOMPILE генерирует новый план при каждом выполнении. Это означает, что плохой выбор значений по умолчанию повлияет на план. На моей последней работе я мог легко продемонстрировать это с помощью некоторого кода отчета: изменение параметров по умолчанию изменило план независимо от предоставленных параметров.
Эта статья о MS Connect интересна: субоптимальное использование индекса в хранимой процедуре (упомянуто в одном из ответов SO ниже)
- Боб Боучемин тоже об этом упоминает
Нерешенные вопросы
Применяется ли сниффинг с RECOMPILE? То есть, если оптимизатор знает, что отказаться от плана, он стремится к повторному использованию?
Почему обнюхиваемые планы "липкие"?
Ссылки с SO:
WHERE
предложении?