首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 效能調優實戰:記憶體管理篇(上)

     編輯:關於SqlServer

前言:記憶體是 SQL Server 的生命線

對 SQL Server 而言,記憶體、磁碟、CPU 三大資源中,記憶體優先級最高。SQL Server 會盡可能將熱點資料頁緩存在記憶體中以降低 I/O。本文系統梳理 SQL Server 記憶體管理體系,分為作業系統層與 SQLOS 內部兩層次。

一、作業系統層面的記憶體管理

1. Windows 關鍵記憶體術語

術語定義
Virtual Address Space (VAS)進程可定址空間。32 位元預設 2 GB 使用者模式(可透過 /3GB 啟動參數擴至 3 GB),啟用 AWE 可擴展至 64 GB(但有缺陷)。
Physical Memory實體記憶體大小。
Reserved Memory預留位址空間(如資料頁緩衝),不可被他用,否則存取違規。
Committed Memory將預留頁面正式提交使用。
Working Set進程位址空間中實際駐留在實體記憶體的部分。
Page Fault虛擬位址不在 Working Set 時觸發。分 Hard Fault(需磁碟 I/O)與 Soft Fault(僅重新導向)。關注 Hard Fault。

2. Windows 記憶體監控計數器

層面關鍵計數器解讀
系統整體Memory: Available MBytes空閒實體記憶體,持續偏低則系統缺記憶體。
Memory: Pages/secHard Page 導致的每秒磁碟頁面讀寫總數(= Pages Input + Pages Output)。
系統自身Memory: Cache Bytes系統 Working Set,即 OS 佔用實體記憶體。
進程級Process: Private Bytes進程提交的非共用位址空間。
Process: Working Set進程駐留在實體記憶體的部分。

工具:效能監視器。參考《使用「效能監視器」監視系統效能/運行狀況》。

二、SQL Server 內部記憶體管理

1. 記憶體用途分類

類別包含項目佔用特徵
Database Cache (資料頁)8 KB 資料/索引頁Reserve 後 Commit,無壓力不釋放,有壓力淘汰 LRU 頁面。
Consumer (功能組件)Connection、General(編譯/鎖/中繼資料)、Query Plan、Optimizer、Utilities多為 Stolen 方式直接 Commit。
Thread Memory每執行緒 0.5 MB固定大小,置於 MemToLeave。
第三方程式碼CLR、Extended Stored Procedure多為 Stolen,CLR 可能用 Reserve/Commit。

2. 依申請方式分類

  • Reserve → Commit:資料頁(Database Page)。
  • Stolen (直接 Commit):除資料頁外幾乎所有 Consumer、執行計畫、連接資訊等。

3. 依申請單位大小分類

  • Buffer Pool:≤ 8 KB 單位(單頁)。
  • Multi-Page (MemToLeave):> 8 KB 單位(大物件、執行緒堆疊、CLR 大物件等)。

記憶體架構示意圖

4. 32 位元 vs 64 位元 記憶體上限差異

環境MemToLeaveBuffer Pool 上限備註
32 位元 Win + 32 位元 SQL384 MB (256 MB + 256 * 0.5 MB * Max Worker Threads)1.664 GB (2 GB - 384 MB)啟用 AWE 可將資料頁擴展至 64 GB,但 MemToLeave 仍 384 MB
64 位元 Win + 32 位元 SQL384 MB3.664 GB (4 GB - 384 MB)核心模式不再佔用使用者 VAS
64 位元 Win + 64 位元 SQL無實際上限無實際上限按需分配,最佳選擇

5. 記憶體使用情況分析兩大工具

效能計數器

計數器含義健康基準
SQLServer:Memory Manager: Total Server Memory (KB)Buffer Pool 提交記憶體應接近 Target Server Memory
Target Server Memory (KB)可用記憶體上限(受 Max Server Memory 限制)—
Memory Grants Pending等待記憶體授權的進程數非 0 即嚴重瓶頸
Buffer Cache Hit Ratio緩衝區命中率穩定 > 98%,< 95% 表示記憶體不足
Lazy Writes/sec每秒惰性寫入緩衝區數頻繁非 0 表示記憶體壓力
Page Life Expectancy (秒)頁面在緩衝池預期停留秒數穩定高值佳,劇烈下降表示壓力
Database Pages / Free Pages / Stolen Pages / Total PagesBuffer Pool 內部結構Total Pages * 8 KB = Total Server Memory

動態管理視圖 (DMV) - Memory Clerk 視角

SQL Server 2005+ 統一由 Memory Clerk 管理所有記憶體申請/釋放。查詢腳本:

SELECT type,
       SUM(virtual_memory_reserved_kb)   AS vm_Reserved_kb,
       SUM(virtual_memory_committed_kb)  AS vm_Committed_kb,
       SUM(awe_allocated_kb)             AS awe_Allocated_kb,
       SUM(shared_memory_reserved_kb)    AS sm_Reserved_kb,
       SUM(shared_memory_committed_kb)   AS sm_Committed_kb,
       SUM(single_pages_kb)              AS SinglePage_kb,   -- Buffer Pool 中 Stolen
       SUM(multi_pages_kb)               AS MultiPage_kb     -- MemToLeave
FROM sys.dm_os_memory_clerks
GROUP BY type
ORDER BY type;

衍生指標:

  • Reserve/Commit = vm_Reserved / vm_Committed
  • Stolen = SinglePage + MultiPage
  • Buffer Pool = vm_Committed + SinglePage
  • MemToLeave = MultiPage

進階:查看緩衝池中具體缓存了哪些表、哪些索引

-- 跨資料庫掃描緩衝描述符
DECLARE @name NVARCHAR(100), @cmd NVARCHAR(1000);
DECLARE dbnames CURSOR FOR SELECT name FROM master.dbo.sysdatabases;
OPEN dbnames;
FETCH NEXT FROM dbnames INTO @name;
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @cmd = 'SELECT b.database_id, DB_NAME(b.database_id) AS db, p.object_id, p.index_id, COUNT(*) AS buffer_count '
             + 'FROM ' + @name + '.sys.allocation_units a, '
             + @name + '.sys.dm_os_buffer_descriptors b, '
             + @name + '.sys.partitions p '
             + 'WHERE a.allocation_unit_id = b.allocation_unit_id '
             + 'AND a.container_id = p.hobt_id '
             + 'AND b.database_id = DB_ID(''' + @name + ''') '
             + 'GROUP BY b.database_id, p.object_id, p.index_id '
             + 'ORDER BY b.database_id, buffer_count DESC';
    EXEC (@cmd);
    FETCH NEXT FROM dbnames INTO @name;
END
CLOSE dbnames; DEALLOCATE dbnames;

-- 依 object_id 查表名
SELECT s.name AS table_schema, o.name AS table_name
FROM sys.objects o JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE o.object_id = @object_id;

-- 依 index_id 查索引名
SELECT name AS index_name FROM sys.indexes WHERE object_id = @object_id AND index_id = @index_id;

查看快取的執行計畫與對應 SQL 文本

SELECT usecounts, refcounts, size_in_bytes, cacheobjtype, objtype, text
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
ORDER BY objtype DESC;

本文側重資料蒐集與架構認知,具體調優手法將在下篇(資料頁、Stolen、Multi-Page 三大壓力專題)詳細說明。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved