Каковы причины отсутствия плана в кэше для хранимых процедур?
WITH RECOMPILE
- Динамический SQL
- Зашифрованный код
- Значительные изменения данных
- Обновить статистику
- Что еще?
Недавно я работал на 2 серверах (SQL Server 2008 R2 и SQL Server 2012), которые не имели планов в кеше для очень ресурсоемких хранимых процедур. Многие, может быть, все операторы внутри хранимых процедур также не имеют планов в кеше. Некоторые из хранимых процедур выполняются довольно часто, например, несколько раз в секунду.
Никакого давления памяти вообще. Один из серверов имеет гораздо больше оборудования, чем необходимо.
Я думал, что отсутствующие планы были связаны с созданием временных таблиц в середине хранимых процедур, но это, похоже, старая информация из SQL Server 2000 или более ранней версии. Начиная с SQL Server 2005, перекомпиляция происходит на уровне операторов для операторов после DDL. Это правда во всех случаях или все еще может случиться на более новых версиях?
Что еще может быть виновником недостающих планов? Я просмотрел несколько статей на эту тему, но ничего не подходит.
Оптимизация для специальных рабочих нагрузок включена на сервере, который я рассматриваю на этой неделе. Одна из хранимых процедур выполняется только один раз в день. У меня есть код для этого. У меня нет кода для того, который выполняется более 100 раз в минуту, но я могу его получить. Я не смогу опубликовать код, но могу описать его в связи с моим вопросом.
Я не верю, что кто-то освобождает кеш процедур или удаляет чистые буферы. Этот клиент использует Solarwinds DPA в качестве одного из инструментов мониторинга. DPA захватил один из планов выполнения для оператора в хранимой процедуре, который вызывается один раз в день. Это утверждение имеет огромное количество операций чтения из-за несергетируемого WHERE
предложения. Если DPA зафиксировало выписку, то это примерный план, который когда-то находился в кэше планов. Просто нет, когда мы устраняем неисправности. Я заставлю их начать входить sp_WhoIsActive
в таблицу.
Я использую sp_BlitzCache
. (Я работаю на Brent Ozar Unlimited). Здесь будет показан план всей хранимой процедуры, а также планы для отдельных операторов, если они существуют. Если они не существуют, он имеет это для предупреждения «Мы не смогли найти план для этого запроса. Возможные причины этого включают динамический SQL, RECOMPILE
подсказки и зашифрованный код». И это предупреждение тоже на заявлениях.
TF 2371 не на месте. Я смотрю статистику ожидания. Сервер довольно скучно. PLE более 130 000
Теперь у меня есть код для еще 2 хранимых процедур. Один из них использует динамический SQL с exec (@sql)
таким, чтобы мы знали, почему нет плана для этого. Но другой, и это тот, который работает более 100 раз в минуту, не имеет ничего необычного. Единственное, что выделяется в этом - это то, что временные таблицы создаются в середине более 1000 строк кода. Это также вызывает кучу дочерних хранимых процедур.
Что касается кэширования планов в SQL Server 2008 , я не вижу никаких литералов> = 8k, но одна из хранимых процедур имеет комментарий о массовой вставке непосредственно перед вызовом другой хранимой процедуры. Но основная вставка не появляется во внешней хранимой процедуре, на которую я смотрю. Раздел «Порог перекомпиляции» статьи интересен. То, что я вижу для временных таблиц, это тонны INSERT (которые могут привести к миллионам строк), некоторые обновления и удаления. Так много данных изменяется во временных таблицах. Миллионы.