Правильно ли я сказал, что статистика используется только при создании плана выполнения хранимой процедуры и не используется в реальном контексте выполнения?
Нет, происходит следующее: план выполнения хранимой процедуры кэшируется. Если предположить, что памяти достаточно для продолжения хранения плана, она не изменится, если не произойдет одно из следующих событий (из раздела Кэширование и повторное использование плана выполнения в документации по SQL Server, выделение выделено):
- Изменения, внесенные в таблицу или представление, на которые ссылается запрос (ALTER TABLE и ALTER VIEW).
- Изменения, внесенные в одну процедуру, которая удаляла бы все планы для этой процедуры из кэша (ALTER PROCEDURE).
- Изменения любых индексов, используемых планом выполнения.
- Обновления статистики, используемые планом выполнения, генерируемые либо явно из инструкции, такой как UPDATE STATISTICS, либо генерируемые автоматически.
- Удаление индекса, используемого планом выполнения.
- Явный вызов sp_recompile.
- Большое количество изменений ключей (генерируемых операторами INSERT или DELETE от других пользователей, которые изменяют таблицу, на которую ссылается запрос).
- Для таблиц с триггерами, если количество строк во вставленных или удаленных таблицах значительно возрастает.
- Выполнение хранимой процедуры с использованием параметра WITH RECOMPILE.
Поэтому, если статистика обновляется, кэшированный план автоматически учитывает новую статистику и перекомпилируется.
Как вы предотвращаете устаревание планов выполнения, если в день добавляется по сто тысяч строк?
Один из них - если в таблице много обновлений, как указано выше. Несколько сотен тысяч измененных строк могут удовлетворить это условие. Но если вы хотите быть уверены или имеете более детальный контроль: обновите свою статистику. Вы можете разрешить SQL Server автоматически создавать и управлять статистикой или вручную делать это самостоятельно. Вы можете найти дополнительную информацию о любом из этих методов в разделах «Автоматическое обновление SQL Server» и «Параметры автоматического создания статистики» . Когда / если вы выполняете еженедельную перестройку индексов, это также приведет к обновлению планов. Проведите некоторое тестирование, чтобы увидеть, что для вас наиболее выгодно, поскольку слишком частое обновление статистики может не дать никаких реальных результатов производительности.
Если мы часто обновляем статистику для решения этой проблемы, имеет ли смысл использовать подсказку OPTION (RECOMPILE) для запроса этой хранимой процедуры?
Вам не нужно использовать RECOMPILE
, так как на основе приведенного выше отрывка вы можете видеть, что план выполнения обновляется соответствующим образом при появлении новой статистики. Возможно, вам подойдет обновление статистики на конец дня (если вы действительно обеспокоены), но я не думаю, что это явно необходимо, исходя из того, что вы сказали до сих пор. Опять же, я бы протестировал его, чтобы увидеть, как это может повлиять на производительность хранимых процедур, и планировать соответственно.
RECOMPILE
не приведет к обновлению статистики в любом случае.Нет, устаревшая статистика может привести к перекомпиляции затронутого утверждения, связанной с оптимальностью .
Субоптимальные планы выполнения, вызванные тем, что значения предикатов находятся за пределами (в частности, выше) диапазона значений, хранимых в соответствующей статистической гистограмме, известны как проблема восходящего ключа . Восстановление статистики - одно из возможных решений, но оно может быть довольно ресурсоемким. Альтернативы включают в себя:
Трассировка флагов 2389 и 2390 . Это требует наличия индекса с проблемным столбцом в качестве ведущего ключа. Он не работает с многораздельными таблицами и эффективен только в SQL Server 2014, если используется исходная оценка мощности. Флаг трассировки 4139 также может потребоваться, если объект статистики является марочным стационарным.
Обновление до SQL Server 2014. Новый оценщик количества элементов содержит логику для оценки за пределами гистограммы с использованием информации о средней плотности. Это может быть менее точным, чем флаги трассировки 2389/2390 при некоторых важных обстоятельствах.
Включите более частые автоматические обновления статистики для больших таблиц с флагом трассировки 2371 . С этим флагом трассировки вместо обновления после 20% + 500 изменений требуются только
SQRT(1000 * Table rows)
модификации . Это не такое полное решение, как упомянутое ранее, поскольку обновления могут запускаться недостаточно часто.Если источником вашей проблемы является не столько частая компиляция планов, основанная на значениях предикатов за пределами гистограммы, но больше о последствиях случайного кэширования такого плохого плана в результате перехвата параметров, вы также можете рассмотреть следующие вопросы:
OPTIMIZE FOR (@parameter = value)
для составления плана для известного представительного значенияOPTIMIZE FOR (@parameter UNKNOWN)
для оптимизации с использованием среднего распределенияOPTIMIZE FOR UNKNOWN
(аналогично 4136, но для каждого запроса)OPTION (RECOMPILE)
для компиляции каждый раз, вынюхивая определенное значение. Если подавляющее большинство значений времени выполнения находится в гистограмме, это может быть эффективным.Для получения дополнительной информации о параметрах сниффинг, встраивание и параметры перекомпиляции см. Мою статью на SQLperformance.com.
источник