SQL Server 2016 的記憶體使用率
我在 Windows Server 上執行 SQL Server 2016 Enterprise Edition,記憶體為 128 GB。在安裝過程中,我為 SQL 伺服器分配了 124 GB,因為伺服器僅用於 SQL,其餘的留給作業系統。
現在,當 DML/DDL 查詢執行或任何維護計劃執行時,每個任務管理器的記憶體消耗高達 97%。但。PLE 保持良好狀態(即 > 300 秒)並且沒有觀察到性能問題。作業和查詢完成後,SQL 很長一段時間都不會釋放記憶體,我必須設置記憶體上限或等待一整天才能釋放記憶體。
除了記憶體上限以及為什麼 SQL 無法在所有作業完成後立即釋放記憶體之外,有什麼方法可以讓 SQL Server 釋放記憶體。
這是設計使然。SQL Server 不會隨意將記憶體還給 Windows,除非 Windows 請求它。
在 SQL Server 執行時,它會在執行事務時開始在記憶體中記憶體數據。這可能包括查詢計劃和數據頁。這是為了避免後續重新編譯相同的計劃或稍後從磁碟讀取相同的數據頁。畢竟,從磁碟讀取比從記憶體讀取要慢得多。一旦 SQL Server 擁有了它想要的記憶體(或者至少是它可以得到的記憶體),就由 Windows 來請求 SQL Server 釋放記憶體。
正如您所說,伺服器上沒有執行其他任何東西,性能不是問題。因此,如果您對使用 124GB 的 SQL Server 沒問題,請開始期望它總是會使用那麼多記憶體。
但是,我建議您查看Jonathan Kehayias 的這篇文章,並將其用作您應該為 SQL Server 提供多少記憶體的基準。
查看 SQL Server 和作業系統的 RAM 分配後,我建議將
max server memory (MB)
SQL Server 實例的設置設置為較低的值。為什麼?和我裸…
Jonathan Kehayias 有一篇文章叫做:
在他的文章中,他解釋了他如何計算為作業系統和 SQL Server 保留的記憶體量:
…在我的書中,我提出的建議是為作業系統保留 1 GB 的 RAM,從 4-16 GB 安裝的每 4 GB RAM 保留 1 GB,然後在 16 GB 以上安裝的每 8 GB RAM 保留 1 GB GB 記憶體。
我根據該公式創建了一個 Excel 圖表,如下所示:
讀出系統上 128 GB 的值,我會將設置
max server memory (MB)
設置為109 GB ( 111616 MB)。這為作業系統和 SQL Server 在max server memory (GB)
設置之外啟動的任何其他任務留出了足夠的記憶體。微軟走得更遠,建議您…
- 從總 OS 記憶體中,減去最大伺服器記憶體控制之外的潛在 SQL Server 執行緒記憶體分配的等價物,它由堆棧大小 1 * 計算的最大工作執行緒 2 組成。
- 然後為最大伺服器記憶體控制之外的其他記憶體分配減去 25%,例如備份緩衝區、擴展儲存過程 DLL、使用自動化過程(sp_OA 呼叫)創建的對像以及來自連結伺服器提供程序的分配。這是一個通用的近似值,里程可能會有所不同。
- 剩下的應該是單個實例設置的 max_server_memory 設置。
參考: 伺服器記憶體配置選項(Microsoft | SQL Docs)
回答您的觀察/問題
現在,當 DML/DDL 查詢執行或任何維護計劃執行時,每個任務管理器的記憶體消耗高達 97%。但。PLE 保持良好狀態(即 > 300 秒)並且沒有觀察到性能問題。作業和查詢完成後,SQL 很長一段時間都不會釋放記憶體,我必須設置記憶體上限或等待一整天才能釋放記憶體。
PLE 是(數據)頁面在記憶體中停留的時間量,以便不會從磁碟重新檢索,這是 IO 會導致延遲。PLE 越高越好。300曾經是一個很好的推薦。越高越好。
當任務管理器中的記憶體管理器達到 97% 時,這可能是因為您的任務
max server memory (MB)
在我引用的文件中概述的設置之外執行。也可能是因為正在將更多數據載入到記憶體中,因為重建索引(讀取數據),重組索引(讀取數據)或執行備份(讀取數據/磁碟IO /任務之外max server memory (MB)
,引用文章中提到的備份緩衝區) .這種行為是意料之中的。由於這些任務,記憶體消耗會增加。
如果你的
max server memory (MB)
值太高,那麼你的伺服器的作業系統可能會與 SQL Server 實例競爭記憶體。當您查詢 SQL Server 記憶體 DMV 時,您可能會觀察到這一點。SELECT system_high_memory_signal_state, system_low_memory_signal_state FROM sys.dm_os_sys_memory;
根據結果,您將了解系統在可用記憶體方面的表現:
system_high_memory_signal_state = 1 Available physical memory is high and system_low_memory_signal_state = 0 system_high_memory_signal_state = 0 Available physical memory is low and system_low_memory_signal_state = 1 system_high_memory_signal_state = 0 Physical memory usage is steady and system_low_memory_signal_state = 0 system_high_memory_signal_state = 1 Physical memory state is transitioning and system_low_memory_signal_state = 0
參考: sys.dm_os_sys_memory (Transact-SQL) ()
除了記憶體上限以及為什麼 SQL 無法在所有作業完成後立即釋放記憶體之外,有什麼方法可以讓 SQL Server 釋放記憶體。
SQL Server 在使用時不會釋放記憶體,因為(正如其他人所指出的):從磁碟檢索數據很昂貴。時間和 IO 方面。
如果記憶體在稍後的某個時間被釋放,那麼這可能是因為數據(頁面)由於頁面(數據、計劃記憶體、其他)的一些老化而從記憶體中釋放
您可以查看
sys.dm_os_process_memory
SQL Server 是否遇到某種形式的記憶體壓力:大多數歸屬於 SQL Server 程序空間的記憶體分配都是通過允許跟踪和記帳這些分配的介面來控制的。但是,記憶體分配可能會在繞過內部記憶體管理常式的 SQL Server 地址空間中執行。值是通過呼叫基本作業系統獲得的。它們不受 SQL Server 內部方法的操作,除非它針對鎖定或大頁面分配進行調整。
參考: sys.dm_os_process_memory (Transact-SQL) (Microsoft | SQL Docs)
我喜歡使用這個查詢:
SELECT dopm.physical_memory_in_use_kb, dopm.process_physical_memory_low, dopm.process_virtual_memory_low, dopm.memory_utilization_percentage FROM sys.dm_os_process_memory dopm;
可能的解決方案
- 查詢 DMV 並確定您的系統是否存在某種形式的記憶體壓力。
- 減少分配給 SQL Server 實例的記憶體量。
- 觀察 PLE。
- 查詢 DMV 並再次確定您的系統是否存在某種形式的記憶體壓力。
- 如果需要,將物理 RAM 添加到 SQL Server。
擁有大量 RAM 通常更好,但有一個最大值,在此之後 SQL Server 的記憶體消耗不會增加,PLE 將保持穩定。