雜湊索引 (Hash Index)

什麼是 Hash Index

利用 Hash 函數把 key 映射到固定範圍的位置,提供 O(1) 等值查詢。

hash(key) → bucket_id → 直接跳到對應 bucket → 找到資料指標
能力 表現
等值查詢 ✅ 極快 O(1)(WHERE id = 123
範圍查詢 ❌ 不支援(hash 打亂順序)
排序 ❌ 不支援(需要全掃並重排)

結構三要素

1. Hash Function

把任意 key 轉成一個整數(hash code)。

hash(key) = key % NUM_BUCKETS   # 簡化示意

好的 hash function 特性:

2. Hash Table(多個 bucket)

Bucket 0 → [key=8  → row#100], [key=12 → row#250]   ← 碰撞
Bucket 1 → [key=5  → row#200]
Bucket 2 → [key=10 → row#300]
Bucket 3 → [key=7  → row#400]

3. Collision Handling

兩個不同 key 落到同一 bucket 時的處理方式。

方式 做法
Chaining(鏈結法) bucket 裡放一個 linked list / array,所有同 bucket 的 key 串起來
Open Addressing(開放位址法) 碰撞時往下一個空位找(線性探測 / 二次探測 / 雙重雜湊)

查詢流程範例

查詢 id = 12

1. hash(12) = 0            # 計算 bucket
2. 去 Bucket 0 找           # 其中有 key=8, key=12 兩筆(碰撞)
3. 在 linked list 中比對 key → 找到 key=12
4. 回傳 row#250 的指標 → 到資料頁讀取實際資料

碰撞少時接近 O(1);碰撞嚴重時退化到 O(n)。


Hash Index vs B-Tree Index

特性 Hash Index 04-Database-Indexing/02-B-Tree-Index
等值查詢 O(1) 很快 O(log n)
範圍查詢 ❌ 不支援 ✅ 高效(有序)
排序支援 ❌ 不支援 ✅ 可直接利用
寫入開銷 較高(需維持平衡)
空間 bucket 多時會浪費 結構比較緊湊
擴容 Rehash 成本高 自動分裂節點
選擇原則

只做等值查詢 → Hash Index;
可能需要範圍 / 排序 / 前綴 → B-Tree Index(預設選它)。


優缺點

優點

缺點


Simplification-with-exceptions

邊界情況

  • 並非所有 RDBMS 都有 Hash Index — MySQL InnoDB 只有 Adaptive Hash Index
    (自動的內部優化);Memory 引擎 才是顯式 Hash Index。PostgreSQL 有明確的
    USING HASH 語法。
  • 分散式系統大量用 Hash — Sharding(hash(user_id) % N)、Consistent Hashing、
    分散式快取(Redis 底層就是 Hash Table)。
  • Covering — Hash Index 只能 exact match,無法 covering index
    式查詢(欄位不在 hash key 中)。
  • Hash join — SQL join 執行計畫中的 Hash Join 也是利用類似概念建立臨時 hash 表。


實際應用

系統 用在哪裡
MySQL Memory HEAP 引擎支援 Hash Index
InnoDB 自動的 Adaptive Hash Index(不可手動建)
PostgreSQL CREATE INDEX ... USING HASH(但使用場景有限)
Redis 底層 dict 就是 Hash Table
分散式 Sharding hash(key) % N02-Distributed-Systems/04-Consistent-Hashing 決定節點
Hash Join SQL 執行計畫在 join 時臨時建立 hash 表