如何从计划缓存中清除临时查询?

Com*_*der 6 sql-server plan-cache sql-server-2014 sql-server-2016

正如标题所暗示的那样,我将仅从 sql server 2014/2016 的计划缓存中删除临时查询(未准备好的查询),因为它占据了我主内存的 50% 以上。你有什么建议吗?

非常感谢。

Sha*_*nky 7

因此,您只想清除 Ad-hoc 查询计划,而仍然不想清除整个过程缓存。您要问的是清除临时 SQL 计划同时保持 SP 计划完整

该博客要求您运行

DBCC FREESYSTEMCACHE('SQL Plans')

根据博客

过程缓存实际上由 4 个不同的缓存存储组成,它们保存不同类型的计划。这些缓存存储是:

  • CACHESTORE_OBJCP - 这些是“对象计划” - 存储过程、函数和触发器。一般来说,好东西。
  • CACHESTORE_SQLCP - 这些是“SQL 计划” - 即席 SQL 语句(包括参数化语句)和准备好的语句。这就是我们所追求的东西。
  • CACHESTORE_PHDR - 所谓的“绑定树”,用于视图、约束和默认值。与讨论的问题无关。
  • CACHESTORE_XPROC - 不是真正的执行计划,而是指向扩展 SP 入口点的指针。

因此,您可以看到有选择地清除 SQLCP 将删除准备好的和临时计划。我在我的系统上测试了这个。

跑查询

select objtype, 
count(*) as number_of_plans, 
sum(cast(size_in_bytes as bigint))/1024/1024 as size_in_MBs,
avg(usecounts) as avg_use_count
from sys.dm_exec_cached_plans
--where objtype='adhoc'
group by objtype
Run Code Online (Sandbox Code Playgroud)

输出是

在此处输入图片说明

您可以看到图片中有1264临时计划和69准备好的报表。

现在我有选择地清除 SQLCPDBCC FREESYSTEMCACHE('SQL Plans')并再次重新运行查询,这给了我下面的输出

在此处输入图片说明

现在您可以看到临时和准备好的计划分别是 2 和 6。而其他不受影响。


小智 4

DECLARE @plan_handle varbinary(64)

DECLARE db_cursor CURSOR FOR 
SELECT plan_handle
FROM sys.dm_exec_cached_plans
WHERE objtype = 'Adhoc' -- and usecounts = 1 -- optional: just delete the ones that are used only once

OPEN db_cursor  
FETCH NEXT FROM db_cursor INTO @plan_handle  

WHILE @@FETCH_STATUS = 0  
BEGIN  
    DBCC FREEPROCCACHE (@plan_handle);  
    FETCH NEXT FROM db_cursor INTO @plan_handle 
END 

CLOSE db_cursor  
DEALLOCATE db_cursor 
Run Code Online (Sandbox Code Playgroud)