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

SQL Server 表掃描深度解析:從執行計畫到資料頁槽位掃描機制

     編輯:關於SqlServer

「表掃描」是效能殺手。本文從執行計畫現象切入,透過 DBCC IND 定位資料頁、DBCC PAGE 剖析頁面內部結構(頁首、資料區、槽位陣列),揭示表掃描**逐槽位掃描**的物理機制。

一、現象:執行計畫顯示 Table Scan

CREATE TABLE Person (ID INT, Name CHAR(100));
INSERT INTO Person VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Cindy');
SELECT * FROM Person WHERE Name = 'Bob';  -- 無索引,Table Scan

Table Scan 執行計畫

二、資料頁在哪裡?DBCC IND 定位

啟用追蹤旗標 2588 觀察 DBCC IND 參數提示。
TRACEON 2588 DBCC IND Help

執行 DBCC IND('db', 'Person', -1):
DBCC IND 輸出

  • PageFID:PagePID = 1:78 為資料頁(IAMFID=NULL 表示自身非 IAM)
  • PageType=1 資料頁、IndexLevel=0 葉層

三、資料頁內部結構:頁首 + 資料區 + 槽位陣列

資料頁結構示意圖

  • 頁首 (96 bytes):頁面屬性、LSI、空間管理資訊
  • 資料區:實際資料列內容,由槽位指向
  • 槽位陣列 (Slot Array):頁尾反向增長,每槽 2 bytes 儲存**資料列在頁內的位移量 (Offset)**

四、DBCC PAGE 實測頁面內容 (Page 78, Option 1/3)

啟用 DBCC TRACEON(3604) 輸出至用戶端。

頁首

頁首資訊

  • m_slotCnt = 3:3 個槽位
  • m_freeCnt = ...:可用空間

資料區

資料區十六進位

槽位陣列

槽位陣列

  • Slot 0: Offset 0x60 (96) → 第一列起始位置(緊接頁首)
  • Slot 1: Offset 0x7E (126)
  • Slot 2: Offset 0x92 (146)

五、表掃描物理機制:逐槽位迭代

  1. 儲存引擎定位資料頁(透過 IAM 鏈遍歷所有資料頁)。
  2. 2. 讀取頁首取得 m_slotCnt。 3. **迴圈 i = 0 到 m_slotCnt-1**:
    • 讀取 Slot i 的 Offset。
    • 跳轉至 Data Area 對應位置讀取資料列。
    • 評估 WHERE 條件,符合則輸出。
    4. 換下一頁,重複直到 IAM 鏈結束。

**本質:表掃描 = 掃描每頁的槽位陣列,依位移量隨機存取資料區。**

六、從理解到優化

  • 槽位掃描需讀取**所有頁面、所有列** → I/O 與 CPU 成本隨資料量線性增長。
  • 建立適當索引 → **Index Seek** 直接定位目標頁/槽,複雜度 O(log N)。
  • 大表無索引查詢 → **並行掃描** 可利用多核心,但總工作量不變。
  • 分割資料表 → 掃描單一分區,縮小範圍。

總結

表掃描在物理層面即「逐頁讀取槽位陣列、依位移量取資料列」。DBCC IND 找頁、DBCC PAGE 看槽位,是理解並消除表掃描的基礎工具組合。

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