為什麼 sys.dm_exec_query_stats 中缺少大多數記憶體計劃?
我試圖了解 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_stats
or中來解釋的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;
這些查詢絕大多數是未參數化的使用者查詢,而不是系統查詢。我通過按 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。