對於能夠被利用的查詢,多列聯合索引在所有情況下都優於 Index Merge(多單列索引合併)。
優化器甚至可能放棄 Index Merge 而選擇全表掃描或單一索引。索引越多,寫入越慢,磁碟佔用越大。
MySQL 5.0+ 引入 Index Merge(索引合併)優化,可同時使用多個單列索引,通過 intersection(交集)、union(並集)、sort-union 三種算法合併結果。但:
(a,b) 直接按 a,b 順序存儲,範圍查詢、排序、覆蓋索引一次到位,零合併開銷。某列不重複值的數量。Cardinality / 總行數 越接近 1,區分度越高。
-- 查看基數
SHOW INDEX FROM tbl_name;
-- 或
SELECT COUNT(DISTINCT col_a), COUNT(DISTINCT col_b) FROM tbl_name;
WHERE a=1 AND b>10,a 放前面,b 放後面;若 b 在前,範圍查詢會導致後續列索引失效。SELECT a,b FROM t WHERE c=1,將 c 放前,a,b 放後可實現覆蓋索引,避免回表。Cardinality(foo)=750,Cardinality(bar)=100(foo, bar):先按 foo 過濾到 ~2 行,再按 bar 精確定位。(bar, foo):先按 bar 過濾到 ~17 行,再按 foo,掃描量增大 8 倍。不再單純按基數排序,需綜合考慮:
建議:收集生產 EXPLAIN 樣本,用 pt-index-usage 分析索引使用率,按「高頻查詢優先滿足」原則設計 2-3 個聯合索引,而非窮盡排列組合。
優化器會進一步統計(如直方圖、平均行長、關聯度)判斷索引是否「足夠高效」。若預估回表成本過高,可能仍選全表掃描。可用
FORCE INDEX強制,但需持續監控執行計劃變化。
MySQL 5.7 Multiple-Column Indexes — 含最左前綴原理、Index Merge 條件、優化器決策細節。
SHOW INDEX 檢查現有單列索引是否可合併為聯合索引。pt-duplicate-key-checker 發現冗餘/重複索引。EXPLAIN 走向。Innodb_rows_read、Handler_read_key 指標變化。少而精 是索引設計鐵律:
✅ 高區分度列左置 ✅ 等值列前範圍列後 ✅ 覆蓋高頻查詢 ✅ 定期清理低用率索引。
多列索引不是萬能銀彈,但對於 OLTP 核心查詢,它是性能與維護成本的最佳平衡點。