Sql-Server

如何從計劃記憶體中清除臨時查詢?

  • March 3, 2021

正如標題所暗示的,我將只從 sql server 2014/2016 的計劃記憶體中刪除臨時查詢(未準備好的查詢),因為它佔用了我主記憶體的 50% 以上。你有什麼建議嗎?

非常感謝。

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 

因此,您只想清除 Ad-hoc 查詢計劃,但仍不想清除整個過程記憶體。您要問的是在保持您的 SP 計劃完整的同時清除您的 Ad-hoc SQL 計劃

部落格要求你執行

DBCC FREESYSTEMCACHE('SQL Plans')

根據部落格

過程記憶體實際上由 4 個不同的記憶體儲存組成,它們保存不同類型的計劃。這些記憶體儲存是:

  • CACHESTORE_OBJCP - 這些是“對象計劃” - 儲存過程、函式和触發器。一般來說,好東西。
  • CACHESTORE_SQLCP - 這些是“SQL 計劃” - 即席 SQL 語句(包括參數化語句)和準備好的語句。這就是我們所追求的東西。
  • CACHESTORE_PHDR - 用於視圖、約束和預設值的所謂“綁定樹”。與討論的問題無關。
  • CACHESTORE_XPROC - 不是真正的執行計劃,而是指向擴展 SP 入口點的指針。

因此,您可以看到有選擇地清除 SQLCP 將刪除準備好的計劃和臨時計劃。我在我的系統上對此進行了測試。

Ran query

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

輸出是

在此處輸入圖像描述

您可以看到圖片有1264臨時計劃和69準備好的報表。

現在我有選擇地使用 SQLCP 清除DBCC FREESYSTEMCACHE('SQL Plans')並再次重新執行查詢,這給了我以下輸出

在此處輸入圖像描述

現在您可以看到 ad-hoc 和準備好的計劃分別是 2 和 6。而其他不受影響。

引用自:https://dba.stackexchange.com/questions/230584