Sql server 更改存储过程是否会使缓存的执行计划过期?

Sql server 更改存储过程是否会使缓存的执行计划过期?,sql-server,sql-server-2008,sql-execution-plan,Sql Server,Sql Server 2008,Sql Execution Plan,对存储过程执行ALTER PROCEDURE语句是否会导致该存储过程的所有缓存执行计划在SQL Server 2008/2005中无效并过期?是 您可以通过执行以下操作来验证这一点 SELECT * FROM sys.dm_exec_procedure_stats where object_id = object_id('YourProc', 'P') 前后 从 [计划将从缓存中删除的情况包括]全局操作,如运行DBCC FREEPROCCACHE从缓存中清除所有计划,以及对单个过程的更改,如

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

您可以通过执行以下操作来验证这一点

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

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


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

  • 创建一个过程
  • 执行几次
  • 通过检查sys.dm_exec_cached_计划确认它已缓存
  • 改变程序
  • sys.dm_exec_cached_计划中的行已消失

    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):

    上述查询产生:

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

    当然,这不是一种永久状态-系统上的其他查询和其他内存压力将决定这些临时查询在缓存中停留的时间。

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


    有时会出现严重的性能问题,我发现显式运行
    DBCC-FREEPROCCACHE
    可以极大地提高系统的性能。当然,如果您知道某个存储过程存在问题,也可以明确清除该存储过程的缓存。

    尽管我相信您(因为您享有很高的声誉),但无论在何处,都可以在MSDN上记录此内容。将找到一个链接。@Aaron-没有明确提到我能看到的
    ALTER PROC
    。仅供参考,我在文档中提出了一个错误。。。请随意投票/评论。Connect项已更新,并承诺更正文档。这是在计划缓存中充满大量一次性临时查询或其他情况下发生的吗?如果是这样的话,对临时工作负载进行优化可能是一种选择。老实说,我已经见过几次了,在第一次尝试解决这一问题时,我花了很多时间,包括承包商在内的所有问题。我们从未到达路由,因为我们只是发现在大量数据库更新之后,有时需要调用
    DBCC FREEPROCCACHE
    objtype  c
    -------  ----
    Adhoc    1