Видалення з процедурного кешу певних планів запитів, Олонца сергей

У цій невеликій замітці я хочу поділитися тим, як з процедурного кешу видалити певні плани запитів. Коли може виникати така необхідність? Наприклад, збережену процедуру запустили з таким параметром, який привів до формування неоптимального плану запиту для збереженої процедури. І швидше за все для цього конкретного випадку план є оптимальним, але частіше цю процедуру використовують зовсім з іншими параметрами, для яких план вже не буде оптимальним. Природно, необхідно попрацювати над такою процедурою і запитами в ній, щоб подібні випадки більше не повторювалися, але в поточний момент нам необхідно прибрати план запиту з кешу, щоб новий запуск збереженої процедури привів до компіляції та формуванню потрібного плану. Природно при цьому ми не хочемо торкнутися інші плани в кеші, щоб не викликати масову перекомпіляцію запитів і зайве навантаження.

Варіант перший, можна змінити збережену процедуру саму на себе. Наприклад в Object Explorer вибрати збережену процедуру, зробити Script Store Procedure as -> ALTER to -> New Query Window і виконати те, що вийшло.

Видалення з процедурного кешу певних планів запитів, Олонца сергей

Script Stored Procedure

Це призведе до того, що під час наступного запуску процедури, що станеться її перекомпіляція. Метод дуже простий і швидкий, але має один недолік: це веде до зміни поля modify_date в системному поданні sys.objects, хоча по суті справи ніяких змін ми не вносили.

Варіант другий, більш складний, зробити запит до системного кончини sys.dm_exec_cached_plans, отримати потрібний хендл (або хендлом) неоптимальні планів і видалити їх з кешу за допомогою DBCC FREEPROCCACHE. Наприклад, у своїй тестовій базі я зроблю такий запит і отримаю значення поля plan_handle.