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

SQL Server 資料頁面結構深度解析:頁頭、資料列、位移陣列與儲存機制

     編輯:關於SqlServer

前言

SQL Server 資料儲存的基本單位是 **8 KB 頁面**。理解頁面內部結構,有助於掌握索引運作、碎片成因、DBCC 指令輸出解讀與效能調優。本文以簡單範例表剖析頁面三大區塊:頁頭、資料區、位移陣列。

頁面整體架構 (8192 Bytes = 8 KB)


+------------------+ 0x00 (位移 0)
|    頁頭 (96 B)   | 固定 96 位元組
+------------------+ 0x60 (位移 96)
|    資料區        | 變長,依資料列大小向上增長
|   (資料列堆疊)   |
|                  |
+------------------+ 動態位移 (向下增長)
|  位移陣列        | 每列 2 位元組,記錄資料列起始位移
|  (Slot Array)    | 由頁尾向前增長
+------------------+ 0x1FFF (位移 8191)

一、頁頭 - 頁面身分證與管理資訊

欄位位移大小說明
page_id06 B檔案號:頁號 (FileID:PageID),如 1:100
header_version61 B版本號
type71 B頁面類型:1=資料頁, 2=索引頁, 10=IAM, 11=PFS...
free_cnt82 B頁面剩餘可用位元組數
min_len102 B資料列最小長度 (用於快速判斷能否插入)
slot_cnt122 B目前資料列數 (Slot 數)
reserved_cnt142 B保留空間 (給前向指標/版本資訊)
lsn1610 B最後修改此頁的 Log Sequence Number
... 其他管理欄位......前向指標、Ghost 記錄計數、檢查碼等
關鍵:free_cnt 指向資料區結尾,**新資料列永遠寫入 free_cnt 位置**,寫入後更新 free_cnt 與 slot_cnt。

二、資料列結構 - 實際資料儲存格式


+----------------+----------------+----------------+----------+----------+
| 狀態位元組     | 固定長度資料   | 變長欄位計數   | 變長位移陣列 | 變長實際資料 |
| (2 B)          | (依定義順序)    | (2 B)          | (每欄 2 B)   |            |
+----------------+----------------+----------------+----------+----------+
  • 狀態位元組:Bit 0=版本資訊存在, Bit 1=前向指標存在, Bit 2=NULL 位圖存在, Bit 3=變長欄位存在...
  • 固定長度資料:依 CREATE TABLE 定義順序緊密排列 (int, datetime, char...)。
  • NULL 位圖:固定長度資料後,每欄 1 bit (含固定/變長欄位),1=NULL, 0=非 NULL。
  • 變長欄位:位移陣列記錄**資料結束位移** (相對資料列起始);實際資料緊接排列。

三、位移陣列 - 秒級定位任意資料列

  • 位於頁面尾部,向前增長。
  • 每個 Slot 佔 **2 位元組**,儲存該資料列在頁面內的**起始位移** (0-based)。
  • Slot 0 對應第一筆資料,Slot N-1 對應第 N 筆。
  • **刪除資料列不重排位移陣列**:Slot 標記為空 (位移 0xFFFF),空間標記為可重用,避免大量資料移動。

四、實戰範例:表 test (a INT, b INT) 在頁面 1:100

插入兩列後頁面狀態


頁頭:
  page_id = 1:100, type = 1, free_cnt = 126, slot_cnt = 2
資料區 (從位移 96 開始):
  Slot 0 (位移 96):  狀態位元組 | a=1 (4B) | b=100 (4B)          -> 長度 10+4+4=18? 實際含 NULL 位圖等
  Slot 1 (位移 114): 狀態位元組 | a=2 (4B) | b=200 (4B)
位移陣列 (從頁尾向前):
  Slot 0 -> 96
  Slot 1 -> 114
free_cnt 更新為 132 (下一筆寫入位置)

五、頁面分裂與碎片成因

  1. **插入導致 free_cnt 不足** → 配置新頁 → 移動約半數資料列到新頁 → 更新 IAM、父索引頁 → **頁面分裂**。
  2. **更新導致資料列變長** (如 VARCHAR 增長) → 原頁空間不足 → **前向指標** 指向新頁新位置 → 讀取需雙跳 (邏輯碎片)。
  3. **刪除留下空洞** → ghost_cleanup 背景執行緒標記 Ghost 記錄 → 空間可重用但位移陣列不重排。

六、DBCC PAGE 實際檢視頁面內容


DBCC TRACEON(3604);  -- 輸出到用戶端
DBCC PAGE (DatabaseName, 1, 100, 3);  -- DB, FileID, PageID, PrintOpt(0-3)
-- PrintOpt: 0=頁頭, 1=頁頭+位移陣列, 2=完整資料列, 3=完整+十六進位

七、效能調優啟示

  • 填充因子:FILLFACTOR = 80 預留 20% 空間,減少分裂 (代價:掃描更多頁面)。
  • 固定長度優先:減少變長欄位、NULL 位圖、前向指標開銷。
  • 窄索引鍵:叢集索引鍵越窄,非叢集索引葉層越小,頁面容納更多列。
  • 定期重建/重組:ALTER INDEX ... REBUILD/REORGANIZE 整理碎片、壓實頁面。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved