Отсутствие планов выполнения для хранимых процедур

12

Каковы причины отсутствия плана в кэше для хранимых процедур?

  1. WITH RECOMPILE
  2. Динамический SQL
  3. Зашифрованный код
  4. Значительные изменения данных
  5. Обновить статистику
  6. Что еще?

Недавно я работал на 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 (которые могут привести к миллионам строк), некоторые обновления и удаления. Так много данных изменяется во временных таблицах. Миллионы.

Тара Кизер
источник
Поскольку у вас есть хранимые процедуры, которые воспроизводят проблему, вы можете создать минимальный пример, который воспроизводит ее, и при этом выяснить проблему?
Мартин Смит,

Ответы:

3

Существует два плановых кэш-файла DMF:

sys.dm_exec_query_plan - возвращает кэшированные планы в формате XML, но только до определенного размера (и только до тех пор, пока они могут быть отформатированы как XML в SQL Server, что означает до 128 вложенных уровней.)

sys.dm_exec_text_query_plan - возвращает кэшированные планы в текстовом формате любого размера. Но недостатком является то, что когда планы большие, вы не можете конвертировать их в XML внутри SQL Server, и даже TRY_CONVERT, поскольку XML возвращает ноль.

sp_BlitzCache работает только с прежним DMV (потому что он должен анализировать планы запросов как XML, чтобы выполнять все виды нарезки и нарезки кубиками). Я сделал проблему Github # 838, чтобы улучшить это, чтобы мы могли по крайней мере предупредить пользователей, чтобы они проверяли sys.dm_exec_text_query_plan на их большие запросы. Однако мы все еще не сможем провести анализ XML.

Брент Озар
источник
И та же причина в sys.query_store_plan.query_planтом nvarchar(MAX), что не XML (мелочи SQL).
Ремус Русану
@RemusRusanu ооо, такие большие планы появляются там! Ницца.
Брент Озар
Мы проверяем, связаны ли отсутствующие планы с тем, что вы нашли. Как только я перезвоню, выложу обновление.
Тара Кизер
Я отмечаю это как ответ, хотя я не получил ответа от клиента. Это единственное, что может остаться, и это имеет смысл, учитывая огромные запросы. Я опубликую обновление, если что-то изменится.
Тара Кизер
@TaraKizer вы делаете это только потому, что ваш ежеквартальный обзор готовится, верно? Я вижу что ты тут делал. БОНУС РАЗБЛОКИРОВАН.
Брент Озар
0

Возможно, вам нужно настроить максимальный размер XML, который SSMS может вернуть в сетку?

Стивен Моррис
источник
Нет, потому что, как отмечает Тара, даже если вы записали ее в таблицу и проверили ее длину, данные не вернутся.
Брент Озар