Які причини відсутності плану в кеші для збережених процедур?
WITH RECOMPILE
- Динамічний SQL
- Зашифрований код
- Значні зміни даних
- Оновити статистику
- Що ще?
Нещодавно я працював на двох серверах (SQL Server 2008 R2 та SQL Server 2012), у яких не було планів кеш-пам'яті для дуже складних процедур, що зберігаються. У багатьох, можливо, всіх висловлювань всередині збережених процедур також не було планів у кеші. Деякі із збережених процедур виконуються досить часто, як кілька разів на секунду.
Жодного тиску пам'яті немає. На одному з серверів є набагато більше апаратного забезпечення, ніж потрібно.
Я вважав, що відсутні плани були пов’язані з тимчасовими створеннями таблиць посеред збережених процедур, але це, здається, стара інформація з SQL Server 2000 або раніше. Починаючи з SQL Server 2005, перекомпіляції відбуваються на рівні операторів для операторів після DDL. Це правда у всіх випадках чи все ж може статися в нових версіях?
Що ще може бути винуватцем відсутніх планів? Я пропустив кілька статей на цю тему, але нічого, здається, не підходить.
Оптимізація навантажень adhoc увімкнена на сервері, на якому я переглядаю цей тиждень. Одна із збережених процедур виконується лише раз на день. У мене є код для цього. У мене немає коду для того, який виконується понад 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, але одна із збережених процедур має коментар щодо об'ємної вставки прямо перед тим, як викликати іншу збережену процедуру. Але об'ємна вставка не відображається у зовнішній збереженій процедурі, яку я переглядаю. Цікавий розділ «Поріг перекомпіляції». Що я бачу для тимчасових таблиць - це тони ВСТАВКИ (які можуть призвести до мільйонів рядків), деякі оновлення та видалення. Так багато даних змінюються у тимчасових таблицях. Мільйони.