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

Не выполнение ALTER PROCEDURE инструкция для хранимой процедуры приводит к тому, что все кэшированные планы выполнения для этой хранимой процедуры становятся недействительными и истекают в SQL Server 2008 / 2005?

3 ответов


Да.

вы можете проверить это, выполнив

SELECT * FROM sys.dm_exec_procedure_stats 
where object_id = object_id('YourProc', 'P')

до и после.

С TechNet

[ситуации, в которых планы будут удалены из кэша, включают] глобальные операции, такие как запуск DBCC FREEPROCCACHE чтобы очистить все планы из кэша, а также изменения в одной процедуре, например ALTER PROCEDURE, который удалит все планы для этой процедуры из кэша.


да. Конечно, это легко проверить самому:

  1. создать процедуру
  2. выполните его несколько раз
  3. подтвердите, что он кэшируется, проверив sys.dm_exec_cached_plans
  4. изменить процедуру
  5. строка в sys.dm_exec_cached_plans ушел

    CREATE PROCEDURE dbo.blat AS SELECT 1; 
    GO 
    EXEC dbo.blat; 
    GO 5
    
    SELECT COUNT(*) 
    FROM sys.dm_exec_cached_plans AS p 
    CROSS APPLY sys.dm_exec_sql_text(p.plan_handle) AS s 
    WHERE [sql].[text] LIKE '%dbo.blat%';
    
    -----
    1
    
    ALTER PROCEDURE dbo.blat AS SELECT 22;
    GO
    
    SELECT COUNT(*) FROM sys.dm_exec_cached_plans AS p
    CROSS APPLY sys.dm_exec_sql_text(p.plan_handle) AS s
    WHERE [sql].[text] LIKE '%dbo.blat%';
    
    -----
    0
    

но если ваша процедура имеет динамический SQL, главная Proc план исчезнет, но планы ребенка (Adhoc / Prepared) будет оставаться.

CREATE PROCEDURE dbo.what
AS
BEGIN
  DECLARE @sql nvarchar(max) = N'SELECT x FROM dbo.flange;';
  EXEC sys.sp_executesql @sql;
END
GO

DBCC FREEPROCCACHE;
GO
EXEC dbo.what;
GO
SELECT objtype, c = COUNT(*) 
  FROM sys.db_exec_cached_plans AS p
  CROSS APPLY sys.dm_exec_sql_text(p.plan_handle) AS t
  WHERE t.text LIKE N'%flange%'
  GROUP BY objtype;
GO

результаты:

objtype  c
-------  ----
Adhoc    1
Proc     1

теперь измените процедуру (но таким образом, чтобы она все еще производила тот же SQL):

ALTER PROCEDURE dbo.what
AS
BEGIN
  SET NOCOUNT ON;
  DECLARE @sql nvarchar(max) = N'SELECT id FROM dbo.flange2;';
  EXEC sys.sp_executesql @sql;
END
GO

запрос выше дает:

objtype  c
-------  ----
Adhoc    1

конечно, это не постоянное состояние-другие запросы и другое давление памяти на систему будут диктовать, как долго эти специальные запросы остаются в кэше.


это - но могут быть и другие факторы.

иногда с серьезными проблемами производительности я обнаружил, что явно работает DBCC FREEPROCCACHE может значительно улучшить производительность системы. Конечно, вы также можете явно очистить кэш для одного sproc, если знаете, что у него возникли проблемы.