Истекает ли изменение хранимой процедуры кэшированных планов выполнения? - PullRequest
9 голосов
/ 06 сентября 2011

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

Ответы [ 3 ]

7 голосов
/ 06 сентября 2011

Да.

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

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

до и после.

С TechNet

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

4 голосов
/ 06 сентября 2011

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

  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

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

1 голос
/ 06 сентября 2011

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

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

...