資料庫索引概論 (Database Indexing Overview)

什麼是索引

索引像書本的 目錄:讓資料庫不用從頭到尾翻整本書(資料表),就能快速找到需要的資料。


沒索引 vs 有索引

CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(100),
  email VARCHAR(100),
  age INT
);

email 做查詢:

SELECT * FROM users WHERE email = 'bohr@example.com';
情境 行為 複雜度
沒索引 Full Table Scan 逐筆比對 O(n)
建立索引 CREATE INDEX idx_email ON users(email); 透過索引跳到對應位置 接近 O(log n)

索引加速哪些操作

操作 範例
條件查詢(等值/範圍) WHERE email = 'x'WHERE age > 20
JOIN 兩表 join 時避免巢狀迴圈全表比對
排序 ORDER BY email(若索引已排序)
前綴搜尋 LIKE 'abc%'(但 '%abc' 無法)

索引的成本(Trade-offs)

索引不是免費午餐

代價 說明
額外儲存空間 索引是獨立結構,每個索引都多佔一份空間
寫入變慢 INSERT/UPDATE/DELETE 時要同步更新所有相關索引
太多索引反而拖效能 每次寫入要跑 N 個索引維護;查詢優化器也要花時間挑選哪個索引

索引策略原則


常見索引種類

索引類型 最適合 不擅長
04-Database-Indexing/02-B-Tree-Index 平衡讀寫、範圍查詢、排序 超高寫入吞吐
04-Database-Indexing/03-LSM-Tree 寫多讀少、時序資料、log 類 單點讀取有放大效應
04-Database-Indexing/04-Hash-Index 等值查詢(WHERE id = 123 範圍查詢、排序
04-Database-Indexing/05-Geospatial-Index 地理座標鄰近搜尋 一般欄位
04-Database-Indexing/06-Inverted-Index 全文檢索、關鍵字搜尋 精確欄位比對

Simplification-with-exceptions

邊界情況

  • Primary Key 一定自帶索引(幾乎所有 RDBMS);UNIQUE 約束也會自動建索引。
  • Covering Index — 索引本身已包含查詢需要的所有欄位,可完全避開回表(index-only scan)。
  • Partial / Filtered Index — 只對符合條件的 row 建索引(如只對 status = 'active'),省空間。
  • Clustered vs Non-clustered — Clustered 直接把資料按索引順序存放(每表只能一個),
    Non-clustered 只存 key → 資料指標。InnoDB Primary Key = Clustered。


決策流程

查詢效能不夠?
  ├─ 等值查詢為主           → Hash Index
  ├─ 範圍 / 排序 / 通用     → B-Tree Index(預設)
  ├─ 寫入量極大             → LSM Tree
  ├─ 地理座標鄰近搜尋       → Geospatial Index
  └─ 全文關鍵字搜尋         → Inverted Index