索引碎片 (Index Fragmentation)

★★★★Draft

FromSQL Server 2025 Query Performance TuningDatabase Internals

📚 From the Books

索引碎片 (Index Fragmentation)Indexing

碎片化是經典話題,傳統觀點是「碎片一定要修」。但修碎片本身有成本,修完資料一變動又得重來,而現代 SSD 上「page 跳來跳去」的代價已大幅降低。核心張力不是「碎片好不好」,而是這些碎片真的傷到你的查詢了嗎、傷多少——再決定要不要動、怎麼動。

🧠 Intuition

TIP

一句話分辨:page split 讓 page 的邏輯順序(雙向鏈結串列)仍然正確,但實體順序錯位——原本相鄰的資料散到不同 extent。範圍掃描本該是順序 I/O,碎片一多就退化成隨機 I/O、read-ahead 失效。

⚖️ Tradeoffs

Internal vs External — 不是所有碎片都是敵人
  • External fragmentation(page 跨 extent 錯位)傷的是大範圍 sequential scan:順序 I/O 變 random I/O、read-ahead 失效。
  • Internal fragmentation(page 沒填滿)不一定壞:留下的空間讓後續 INSERT/UPDATE 不必再 split,反而對寫入有利。
  • 所以「碎片率高」不能一概而論——要看是哪一種、以及你的負載是掃描重還是寫入重。
Fill Factor — 空間換 split 成本
  • 建索引時指定 FILLFACTOR(如 80)讓每個 leaf page 只填 80%、留 20% 給未來插入,降低 page split 機率。
  • 太小 → page 數變多 → 大範圍 scan 要讀更多 page、I/O 增加。
  • 太大(接近 100)→ 沒有緩衝空間 → split 機率高。
  • 對 sequential key 幾乎不需要 fill factor(插入都在尾端);對 random key 才有意義。
Heap 的 forwarding pointer — 修碎片代價更高
  • heap 表也會碎片化,但修整時若用 ALTER TABLE ... REBUILD所有 nonclustered index 必須一起重建——因為它們透過 RID(實體位置)指向資料,而資料剛被搬家。
  • 修 heap 碎片的代價因此遠比修 clustered index 高。
  • 這也是 heap 不宜作為主流 OLTP 設計的原因之一。
偵測 — sys.dm_db_index_physical_stats 的三種模式
  • 最重要的 DMV,關鍵欄位:avg_fragmentation_in_percent(邏輯碎片百分比)、avg_page_space_used_in_percent(頁密度)、fragment_countpage_count
  • 三種掃描模式:Limited(預設、最快最粗)、Sampled(抽 1% page、速度與準確度平衡)、Detailed(掃所有 page、最準最重)。
  • 注意:不指定 OBJECT_ID 又設 Detailed,會對整個資料庫所有索引做完整掃描,可能讓 production 陷入維護級 I/O 衝擊;另外索引不到 10,000 page 時,即使選 Sampled 也會自動升級為 Detailed。
REBUILD vs REORGANIZE — 徹底重建 vs 就地整理
  • REBUILD:drop + create 整個索引,重建統計資訊(含 fullscan),成本高;預設上 schema-mod 鎖,可加 ONLINE。適合高度碎片。
  • REORGANIZE:只在 leaf level 就地整理 page,online、可中斷恢復、不更新統計,成本低。適合中度碎片。
  • 經典 Microsoft 粗略規則:0–5% 別動、5–30% REORGANIZE、>30% REBUILD——但這只是指引,重點仍是查詢效能是否實際受影響。
碎片什麼時候才真的有害 — 掃描 vs 點查、HDD vs SSD
  • 小範圍查詢/點查對碎片幾乎無感:只讀單頁時,誰跟誰實體相鄰根本不重要。
  • 大範圍 scan 受害最深:碎片把 sequential I/O 打成 random I/O、read-ahead 也失效,這才是實測中修整前後差距最大的地方。
  • 硬體也改變結論:現代 SSD/NVMe 上「page 跳來跳去」的隨機存取代價已大幅降低,讓「一定要修碎片」的老規則更站不住腳。

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading