索引是資料庫效能的靈魂。本文系統梳理 MySQL 索引底層結構、設計六大黃金原則、B-Tree 與 Hash 索引適用邊界、叢集與二級索引架構,並給出避坑清單,助您從「會建索引」進階到「懂索引優化」。
CHAR/VARCHAR 可指定長度,BLOB/TEXT 必須指定長度。MyISAM/InnoDB 5.1+ 前綴上限 1000 bytes (注意多位元組字符集換算)。CHAR/VARCHAR/TEXT,不支援前綴。SPATIAL 類型,採用 R-Tree。USING BTREE。索引作用於過濾、關聯、排序階段;輸出列走不走索引由覆蓋索引決定。
性別、狀態碼等低基數列建索引幾無收益;唯一鍵、身分證、手機號等高基數列效果最佳。
CHAR(200) 列若前 20 字元已唯一,建 INDEX(name(20)) 可大幅縮小索引體積、提升緩存命中率、加快比較速度。
查詢條件必須從索引最左列開始連續匹配;WHERE b=1 或 WHERE a=1 AND c=3 皆無法用到 (a,b,c) 索引。
LIKE '%suffix'、STRCMP()、函數運算 (如 WHERE YEAR(date)=2023) 皆導致索引失效。
| 特性 | B-Tree (InnoDB/MyISAM 預設) | Hash (Memory 預設) |
|---|---|---|
| 支援運算子 | =, <, >, >=, <=, BETWEEN, LIKE 'abc%' | 僅 = 和 <=> |
| 範圍查詢 | ✓ 極佳 | ✗ 全表掃描 |
| 排序支援 | ✓ ORDER BY 可用索引 | ✗ 無序,需 filesort |
| 最左前綴 | ✓ 支援複合索引前綴匹配 | ✗ 必須完整鍵值匹配 |
| 適用場景 | 通用 OLTP、範圍、排序、分組 | 純等值查找、查找表、緩存表 |
SELECT id, name FROM t WHERE name='x' 若有 INDEX(name, id),二級索引葉子已包含所有需求列,免回表,效能提升數量級。WHERE phone=13800000000 (phone 為 VARCHAR) 導致全表掃描,必須 WHERE phone='13800000000'。WHERE DATE(create_time)='2023-01-01' → 改 WHERE create_time >= '2023-01-01' AND create_time < '2023-01-02'。WHERE a=1 OR b=2 若 a、b 無複合索引,通常全表掃描;改 UNION ALL 或建 INDEX(a,b) 配合條件下推 (ICP)。LIMIT 1000000, 10 仍需掃描 100 萬行;改用延遲關聯或游標式分頁 (WHERE id > last_id LIMIT 10)。ANALYZE TABLE 更新統計,避免優化器誤判。索引設計是「空間換時間」的藝術。掌握 B+Tree 結構特性、最左前綴、覆蓋索引、回表代價,結合 EXPLAIN 觀察 type、key、rows、Extra 四大指標,持續迭代索引策略,才能在業務增長中保持查詢效能線性穩定。