Sql server 如何清除sql server中1个存储过程的缓存

Sql server 如何清除sql server中1个存储过程的缓存,sql-server,Sql Server,我正在使用SQLServer2008R2 我知道DBCC FREEPROCCACHE将清除SQL Server中所有存储过程的缓存 但我需要的是只清除1个存储过程的缓存。我该怎么做 存储过程名称为Rpt\u RegionReport。我不想使用带有重新编译选项的执行存储过程。DBCC FreeProcCache有一个可选参数—要删除的执行计划的ID 您可以使用sys.dm_exec_cached_plans找到要删除的计划,然后将其用作 DBCC FREEPROCCACHE (0x0123456

我正在使用SQLServer2008R2

我知道
DBCC FREEPROCCACHE
将清除SQL Server中所有存储过程的缓存

但我需要的是只清除1个存储过程的缓存。我该怎么做


存储过程名称为
Rpt\u RegionReport
。我不想使用带有重新编译选项的
执行存储过程。

DBCC FreeProcCache
有一个可选参数—要删除的执行计划的ID

您可以使用
sys.dm_exec_cached_plans
找到要删除的计划,然后将其用作

DBCC FREEPROCCACHE (0x0123456....);

只需使用此查询找到计划并清除计划句柄

SELECT [text], cp.size_in_bytes, plan_handle
FROM sys.dm_exec_cached_plans AS cp
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
WHERE cp.cacheobjtype = N'Compiled Plan'
AND cp.objtype = N'Adhoc'
AND cp.usecounts = 1
ORDER BY cp.size_in_bytes DESC;

DBCCFREEPROCCACHE(0x0600010069AB592540C10089000000000000000000000000)

Plan_handle

由@mohan给出的查询可能有一些问题,因为它只过滤对象类型为Adhoc,这意味着排除过程的所有其他查询将显示在此处

因此,请执行以下一组语句,以选择性地仅清除所选过程的执行计划

--Enter Name of your Procedure. I have used here as 'SP_PrepareCustomers'. You should replace it with the name of your procedure. 
DECLARE @NameOfProcedure VARCHAR(255) = 'SP_PrepareCustomers'

DECLARE @planHandle VARBINARY(64) = (SELECT top 1 plan_handle
   FROM   sys.dm_exec_cached_plans AS cp
          CROSS APPLY sys.dm_exec_sql_text(plan_handle)
   WHERE  cp.cacheobjtype = N'Compiled Plan'
          AND cp.objtype = N'Proc'
          AND cp.usecounts = 1
          AND TEXT LIKE '%' + @NameOfProcedure + '%')

IF @planHandle IS NOT NULL
  BEGIN     
      PRINT 'Procedure with name like ' + @NameOfProcedure + ' plan handle found with value as given below:'
      PRINT @planHandle   
      DBCC FREEPROCCACHE (@planHandle)
      PRINT 'Execution plan cleared for the procedure'
  END
ELSE
  BEGIN
      PRINT 'No Plan was found for the selected procedure '
            + @NameOfProcedure
  END 

以下是仅针对存储过程从缓存中删除计划的另一种方法:

DECLARE @PlanHandle VARBINARY(64);

SELECT  @PlanHandle = deps.plan_handle
FROM    sys.dm_exec_procedure_stats AS deps
WHERE   deps.object_id = OBJECT_ID('dbo.SomeProcedureName') AND deps.database_id = DB_ID();

IF @PlanHandle IS NOT NULL
    BEGIN
        DBCC FREEPROCCACHE(@PlanHandle);
    END
GO

在存储过程上执行
sp\u重新编译
难道不起作用吗

EXEC sp_recompile N'SP_Name'; 

为什么?你想解决什么问题?我只测试这个存储过程,不想干扰其他存储过程缓存我认为你不应该有
cp.objtype=N'Adhoc'和cp.usecounts=1
,因为它可能会过滤掉有问题的计划。您不应该假设有人在进行测试,这是在从SSMS命中进程;用户可以通过应用程序代码或测试框架点击程序。根据.awesome的MSDN页面,和
usecounts
可以“在使用showplan时增加多次”。我通过这个查询得到了计划句柄:
从sys.dm_exec_cached_plans中选择cp.plan_句柄cp CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle)st其中OBJECT_NAME(st.objectid,st.dbid)='Rpt_RegionReport'
然后将其存储在一个变量中并将其传递给
DBCC FREEPROCCACHE