MySQL 索引建立指南:何時需要、何時避免、常見誤區深度解析
索引能提升查詢效率、降低 IO 與排序成本,但並非越多越好。本文從四大核心判斷標準、索引過多的副作用、Oracle 位圖索引對比,系統闡述索引設計決策。
一、必須建立索引的四大場景
- 高頻 WHERE 條件欄位:分析所有 SQL,出現頻率高的欄位優先建立。
- 高選擇性(基數大)欄位:唯一值佔比高(如 ID、手機號),索引掃描回表少,效率高。
- 低更新頻率欄位:讀多寫少,或「被檢索幾十次才更新一次」的欄位適合;高頻更新欄位(如最後登入時間)建索引會拖垮寫入效能。
- JOIN 關聯欄位:經常與其他表關聯查詢的外鍵欄位。
二、不適合建立索引的三大反模式
- 低基數欄位:如狀態、性別、類型(僅幾個固定值)。索引掃描會導致同一數據頁重複讀取、丟棄,IO 暴增。
- 超長文本/Blob 欄位:索引體積大、維護成本高,改用全文索引或應用層搜尋引擎。
- 永不出現在 WHERE/ORDER BY/GROUP BY 的欄位:純粹增加寫入負擔。
三、復合索引設計原則(左前綴原則)
- 主列選擇性最高的欄位。
- 多欄位經常
AND 同時出現 → 適合復合索引。
- 欄位常單獨查詢 → 拆分為單列索引。
- 超過 3 欄位慎建,評估必要性。
- 已有單列索引時,同欄位復合索引通常可刪除。
四、索引過多的代價
- 儲存空間佔用(每個索引一棵 B+ 樹)。
- INSERT/UPDATE/DELETE 需同步維護所有索引,寫入放大明顯。
- 優化器統計資訊複雜,可能誤選執行計劃。
五、Oracle 位圖索引對比補充
Oracle 位圖索引適合:
- 基數極小欄位(性別、婚姻狀態)。
- WHERE 條件含多個
AND/OR 組合的低基數欄位。
- 需查詢
IS NULL 的欄位(B-tree 索引不存 NULL)。
MySQL 無原生位圖索引,低基數場景建議:覆蓋索引、分區表 或應用層緩存。
六、實戰檢核清單
[ ] 表行數 > 300 有索引
[ ] PK/FK 必有索引
[ ] JOIN 欄位有索引
[ ] 高頻 WHERE 欄位有索引
[ ] 索引列長度盡量短 (VARCHAR(20) 優於 VARCHAR(255))
[ ] 定期清理無用/重複索引
[ ] 高寫入表索引數控制在 5 個以內