索引是關係型資料庫效能核心。本文從 B+樹儲存原理出發,系統講解 4 大索引類型、單列 vs 複合索引、最左前綴原理、EXPLAIN 執行計畫逐欄位解讀,最後客觀分析索引寫入開銷與空間代價。
| 類型 | 建立語法 | 約束 | 適用場景 |
|---|---|---|---|
| 普通索引 | CREATE INDEX idx ON tbl(col); / ALTER TABLE ADD INDEX | 無唯一性 | 高頻篩選、排序、分組欄位 |
| 唯一索引 | CREATE UNIQUE INDEX / ALTER TABLE ADD UNIQUE | 值唯一、允許 NULL (多 NULL) | 業務鍵 (Email、身分證)、防重複 |
| 主鍵 | PRIMARY KEY (col) / ALTER TABLE ADD PRIMARY KEY | 唯一 + NOT NULL、每表僅一個 | 實體識別、叢集索引基準 |
| 全文索引 | FULLTEXT INDEX (MyISAM 5.6+ InnoDB) | VARCHAR/TEXT 全文搜尋 | 自然語言搜尋、MATCH...AGAINST |
表 people(fn, ln, age),複合索引 idx_fn_ln_age (fn, ln, age)
WHERE fn='John' AND ln='Doe' AND age=30:單次樹搜尋直達複合索引 (a,b,c) 等效於 (a,b,c)、(a,b)、(a) 三索引。可用場景:
WHERE a=1 AND b=2 AND c=3WHERE a=1 AND b=2WHERE a=1不可用:WHERE b=2、WHERE c=3、WHERE b=2 AND c=3 (斷層)
EXPLAIN SELECT * FROM people WHERE fn='John' AND ln='Doe' AND age=30;
| 欄位 | 範例值 | 解讀 |
|---|---|---|
| table | people | 查詢表名 |
| type | ref | 非唯一索引等值查找,良好類型 |
| possible_keys | idx_fn_ln_age | 理論可用索引 |
| key | idx_fn_ln_age | 實際使用索引 (NULL=全掃) |
| key_len | 102 | 使用索引長度 (fn 50 + ln 50 + age 2) |
| ref | const,const,const | 比較值來源 (常數/欄位/函數) |
| rows | 1 | 預估掃描行數 (越小越好) |
| Extra | Using where | 附加資訊 (Using index=覆蓋索引、Using filesort=需排序) |
紅旗:type=ALL (全掃)、key=NULL、rows 巨大、Using temporary/Using filesort
| 缺點 | 影響 | 緩解 |
|---|---|---|
| 空間佔用 | 索引檔可能超過資料檔,受 OS 檔案大小限制 | 只建必要索引、短索引、定期 OPTIMIZE |
| 寫入降速 | INSERT/UPDATE/DELETE 需同步維護所有索引 | 批次寫入、DISABLE KEYS (MyISAM)、延遲索引維護 |
| 統計失效 | 資料分佈變化導致優化器誤判 | 定期 ANALYZE TABLE |
EXPLAIN 定位全掃描Using index)大型系統中,索引設計優於硬體升級。投資時間分析 EXPLAIN,回報率極高。