索引是 SQL 優化的核心槓桿。本文系統整理 MyISAM/InnoDB 索引存儲差異、B+Tree/HASH 選擇、優化器使用條件、6 大經典失效場景、覆蓋索引最佳實踐、Handler 監控指標體驐。
| 引擎 | 數據存儲 | 索引存儲 | 索引類型 | 核心特征 |
|---|---|---|---|---|
| MyISAM | .MYD | .MYI (獨立) | B+Tree | 非聚簇,葉子節點存數據指針 |
| InnoDB | 表空間 (.ibd/.ibdata) | 同表空間 | B+Tree | 聚簇索引:主鍵葉子存全行;二級索引葉子存主鍵 |
| MEMORY | 內存 | 內存 | Hash / B+Tree | Hash 僅支持等值,重啟丟失 |
前綴索引:CREATE INDEX idx_name ON tbl(col(4)) 截取前 4 字符,大幅縮小體積,適用高基數長列。
(a,b,c) 僅 a、a,b、a,b,c 可用LIKE 'prefix%' 右側通配符MATCH...AGAINSTIS NULL 條件Extra: Using index 避免回表| # | 場景 | 根因 | 對策 |
|---|---|---|---|
| 1 | 優化器選擇全表掃描 | 掃描比例 > 30%、統計信息過期 | ANALYZE TABLE、FORCE INDEX |
| 2 | MEMORY 表非等值查詢 | Hash 索引限制 | USING BTREE 或遷移 InnoDB |
| 3 | OR 分割導致失效 | idx_col=1 OR non_idx=2 | 拆分 UNION ALL、建組合索引 |
| 4 | 非最左前綴 | INDEX(a,b) 查 b=1 | 調整索引順序、補單列索引 |
| 5 | LIKE 左側通配符 | LIKE '%abc' | 全文索引、反轉存儲 |
| 6 | 字符串隱式轉換 | str_col = 123 | 參數綁定、強制轉字符串 |
-- 查詢 SELECT a,b FROM t WHERE a=1 AND b=2
-- 建立 INDEX(a,b,c) 即為覆蓋索引,Extra 顯示 Using index
-- 二級索引葉子已包含 a,b,c + 主鍵,無需回聚簇索引
SHOW STATUS LIKE 'Handler_read_%';
| 指標 | 含義 | 健康基準 |
|---|---|---|
Handler_read_key | 索引讀取次數 | 高 = 好 |
Handler_read_rnd_next | 全表掃描次數 | 高 = 差,需建索引 |
Handler_read_next | 範圍掃描次數 | 正常 |
Handler_read_rnd | 排序/臨時表讀取 | 高 = 文件排序 |
黃金比率:Handler_read_key / (Handler_read_key + Handler_read_rnd_next) > 90%
INDEX(a) + INDEX(a,b) → 保留後者)ANALYZE TABLE 更新統計信息pt-online-schema-change 無鎖變更Handler_read_rnd_next 暴增告警