Sql-Server

為什麼 sys.dm_exec_query_stats 中缺少大多數記憶體計劃?

  • March 22, 2022

我試圖了解 SQL Server 2016 SP3 系統上的一些執行計劃記憶體元數據,但我無法將看到的內容與文件相協調。

文件sys.dm_exec_cached_plans說它包含:

SQL Server 為加快查詢執行而記憶體的每個查詢計劃的一行。

在我觀察的系統上,這個視圖現在有 41,283 行。其中絕大多數(37,594 行)是 cacheobjtype = “Compiled Plan” 和 objtype = “Adhoc”。

文件sys.dm_exec_query_stats說它包含:

記憶體計劃中的每個查詢語句一行,並且行的生命週期與計劃本身相關聯。當從記憶體中刪除計劃時,相應的行將從該視圖中刪除。

我希望此視圖中至少有 37,594 行(每個記憶體計劃一個,如果某些記憶體計劃有多個語句,則可能更多)。但是,此視圖總共有 6,867 行。

這種差異是如此之大,以至於我必須假設我誤解了這些觀點應該是什麼。

sys.dm_exec_query_stats有人可以幫我理解為什麼與 相比有這麼少的行sys.dm_exec_cached_plans嗎?

我嘗試在 上將表內部連接在一起plan_handle,唯一的匹配是 1:1 - 換句話說,有數以萬計的記憶體計劃沒有“查詢統計”行。

我還認為這種差異可能是由許多行在sys.dm_exec_procedure_statsor中來解釋的sys.dm_exec_trigger_stats,但事實並非如此(分別為 93 行和 2 行)。

對於任何對這個問題的“為什麼”感到好奇的人,我想看看記憶體中的各種計劃有多老,除了加入sys.dm_exec_query_stats和檢查之外,我不確定有什麼方法可以做到這一點creation_time


以下是我用來獲取上述數字的查詢:

-- total cached plans
SELECT COUNT_BIG(*) AS total_cached_plans
FROM sys.dm_exec_cached_plans decp

-- totals by type
SELECT decp.cacheobjtype, decp.objtype, COUNT_BIG(*) AS plan_count
FROM sys.dm_exec_cached_plans decp
GROUP BY decp.cacheobjtype, decp.objtype
ORDER BY decp.cacheobjtype, decp.objtype;

-- total query stats
SELECT COUNT_BIG(*) AS total_query_stats
FROM sys.dm_exec_query_stats;

SSMS 中上述查詢結果的螢幕截圖,數字如問題中所述


這些查詢絕大多數是未參數化的使用者查詢,而不是系統查詢。我通過按 SQL 文本(從 中提取)排序來驗證這一點sys.dm_exec_sql_text。一些例子:

  • 5,000 條不同的“INSERT INTO”語句針對具有不同文字值的同一張表
  • 具有不同 WHERE 子句的 15,000 個不同的“SELECT COUNT(*)”查詢
  • 針對具有不同文字值的幾個表的 15,000 個不同的“更新”語句

這些都是連接到該伺服器的應用程序送出的合法查詢。

您的許多查詢都符合簡單參數化的條件。

SQL Server 創建語句的參數化版本並將其記憶體為準備好的計劃。

您看到的臨時計劃只是指向參數化版本的shell 。

中的條目sys.dm_exec_query_stats僅與準備好的計劃相關聯。

有關更多背景資訊,請參閱我的文章Simple Parameterization and Trivial Plans

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