更改存储过程是否会使缓存的执行计划失效?

时间:2011-09-06 13:18:57

标签: sql-server sql-server-2008 sql-execution-plan

为存储过程执行ALTER PROCEDURE语句是否导致该存储过程的所有缓存执行计划变为无效并在SQL Server 2008/2005中过期?

3 个答案:

答案 0 :(得分:7)

您可以通过执行

来验证这一点
SELECT * FROM sys.dm_exec_procedure_stats 
where object_id = object_id('YourProc', 'P')

之前和之后。

来自TechNet

  

[将从缓存中删除计划的情况包括]全局操作,例如运行DBCC FREEPROCCACHE以清除缓存中的所有计划,以及更改单个过程,例如ALTER PROCEDURE从缓存中删除该过程的所有计划。

答案 1 :(得分:4)

是。当然,这很容易测试自己:

  1. 创建程序
  2. 执行几次
  3. 通过检查sys.dm_exec_cached_plans
  4. 确认它已缓存
  5. 更改程序
  6. 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
    
  7. 但是,如果您的程序具有动态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
    

    当然这不是永久状态 - 系统上的其他查询和其他内存压力将决定这些即席查询在缓存中保留多长时间。

答案 2 :(得分:1)

确实如此 - 但可能还有其他因素。

有时出现严重的性能问题,我发现明确运行DBCC FREEPROCCACHE可以极大地提高系统的性能。当然,如果你知道它有问题,你也可以明确地清除单个sproc的缓存。