這是一個 SQL Server 2016 CU2 實例,最大 RAM 使用量配置為 15 GB。 MDOP 為 4。
問題:由於記憶體耗盡,每週所有查詢都會進入 RESOURCE_SEMAPHORE 狀態,即使該伺服器中沒有同時執行其他查詢也是如此。實例重新啟動後,查詢再次開始工作。透過下面的圖像,您會注意到我們缺少最大工作空間內存,並且這些查詢確實非常糟糕(查詢成本天文數字)。
重新啟動之前:只有 1.8 GB 可用最大工作空間內存,並且所有錯誤查詢都會進入 RESOURCE_SEMAPHORE 狀態。
實例重新啟動後:大量工作區記憶體(~11GB)並且不再有 RESOURCE_SEMAPHORE,即使對於糟糕的查詢也是如此。
正如您所看到的,這是一個令人厭惡的查詢,需要約 2GB 的 RAM。在此圖中,SSMS 顯示實際上已授予所需的記憶體 - 因為實例已重新啟動。重新啟動之前,記憶體授予保持為 NULL,查詢保持在 RESOURCE_SEMAPHORE 等待狀態。
現在,我們想知道的是:為什麼最大工作空間記憶體會隨著時間的推移而減少,並且在沒有查詢運行時不會被釋放?
答案1
看起來在總共分配的 15 728 640 000 位元組記憶體中,被盜的伺服器記憶體佔用了 12 828 864 000 位元組,顯然沒有足夠的空間用於正常操作。
文檔中說 SQL Server,記憶體管理器對象:
被盜的伺服器記憶體 (KB)
指定伺服器用於資料庫頁面以外的目的的記憶體量。
一個回答說更多:
被盜記憶體描述了用於排序或雜湊操作(查詢工作區記憶體)的緩衝區,或用作通用記憶體儲存的緩衝區,用於分配以儲存內部資料結構(例如鎖定、事務上下文和連接資訊) 。不允許惰性寫入器程序將被盜的緩衝區從緩衝池中刷新。
浪費的查詢顯然執行了龐大的排序操作,然後 SQL Server 不會釋放分配的記憶體。記憶體取自緩衝池,不能用於其他用途。
你沒有太多選擇:
- 改進該查詢,使其不會對大量資料進行排序
- 向 SQL Server 新增更多記憶體
- 定期重新啟動 SQL Server,尤其是在執行此查詢後。