MySQL 索引分 B-Tree(含 B+Tree) 與 Hash 兩大類,不同存儲引擎支援不同。本文系統整理適用條件、限制、建立策略與選擇性分析。
| 場景 | 範例 | 說明 |
|---|---|---|
| 全值匹配 | order_id = '123' | 等值查詢,最理想 |
| 最左前綴匹配 | 聯合索引 (user_id, date) → WHERE user_id=1 | 僅用最左列可用 |
| 列前綴匹配 | order_sn LIKE '134%' | 非 %xxx 開頭 |
| 範圍查詢 | create_time > '2015-01-09' AND create_time < '2015-01-10' | >、<、BETWEEN |
| 精確匹配左列 + 範圍右列 | user_id=1 AND create_time > '2016-09-18' | 左列等值,右列範圍 |
| 覆蓋索引 | SELECT id, name FROM t WHERE id > 100 | 索引包含所有查詢列,避免回表 |
INDEX(a,b,c),WHERE b=1 不走索引INDEX(日期,姓名,電話),WHERE 日期=... AND 電話=... 僅用「日期」NOT IN、<> 不走索引(全表掃描)WHERE a=1 AND b>2 AND c=3,「c」無法用索引=、IN)ORDER BY/GROUP BY 臨時表排序-- 錯誤
WHERE TO_DAYS(out_date) - TO_DAYS(NOW()) <= 30
-- 正確
WHERE out_date < DATE_ADD(NOW(), INTERVAL 30 DAY)
選擇性 = COUNT(DISTINCT col) / COUNT(*),越接近 1 越好SELECT
COUNT(DISTINCT LEFT(account, 10)) / COUNT(*) AS sel10,
COUNT(DISTINCT LEFT(account, 15)) / COUNT(*) AS sel15
FROM t;
-- 選擇性接近全列時,採用該前綴長度
索引是資料庫效能杠桿,但需「精準施力、定期複盤」。