延續基礎索引類型,本文聚焦實戰核心:組合索引「最左前綴」匹配機制深度解析、索引建立決策框架、LIKE 模糊查詢索引失效邊界、以及函數運算導致的索引失效陷阱與改寫技巧。
組合索引 INDEX idx_a_b_c (a, b, c) 的 B+ 樹鍵值按 (a, b, c) 元組排序。查詢能否用到索引,取決於 WHERE 條件是否包含索引最左邊的連續列。
WHERE a = 1
WHERE a = 1 AND b = 2
WHERE a = 1 AND b = 2 AND c = 3
WHERE a = 1 AND b > 2 -- 範圍查詢停在 b,c 無法用到
WHERE a = 1 ORDER BY b, c -- 排序也能用到
WHERE b = 2 -- 缺少最左列 a
WHERE b = 2 AND c = 3 -- 缺少最左列 a
WHERE a = 1 AND c = 3 -- 跳過 b,c 無法用到(中斷連續性)
WHERE a > 1 AND b = 2 -- a 範圍查詢,b 後續列失效
a, b 為等值,c 為範圍/排序 → INDEX (a, b, c)(a,b) 已覆蓋單列 a,無需額外建 INDEX (a)WHERE、JOIN ON 高頻出現的列ORDER BY、GROUP BY 高頻列(配合 WHERE 列組合索引)MySQL 僅對以下操作符使用索引:
<, <=, =, >, >=, BETWEEN, IN, LIKE 'prefix%'
不使用索引:LIKE '%suffix'、LIKE '%mid%'、!=、<>、NOT IN、函數運算、隱式轉換。
| 查詢 | 索引 | 說明 |
|---|---|---|
WHERE name LIKE 'admin%' | ✅ 生效 | 固定前綴,B+ 樹範圍掃描 |
WHERE name LIKE '%admin' | ❌ 失效 | 前導通配符,全表掃描 |
WHERE name LIKE '%admin%' | ❌ 失效 | 雙邊通配符,全表掃描 |
解決方案:全文索引(FULLTEXT)、倒排索引、或應用層搜尋引擎。
-- ❌ 錯誤:每行計算 YEAR(),索引失效,全表掃描
SELECT * FROM users WHERE YEAR(create_time) < 2007;
-- ✅ 正確:常量預計算,索引範圍掃描
SELECT * FROM users WHERE create_time < '2007-01-01';
-- ❌ 錯誤:欄位參與運算
SELECT * FROM orders WHERE amount * 1.1 > 100;
-- ✅ 正確:常量移等號右側
SELECT * FROM orders WHERE amount > 100 / 1.1;
-- 欄位 varchar,傳入數字 → 隱式轉換,索引失效
SELECT * FROM users WHERE phone = 13800138000;
-- 修正:字串字面量
SELECT * FROM users WHERE phone = '13800138000';
NOT EXISTS 或 LEFT JOIN ... IS NULLUNION 改寫,否則多數全表掃描索引優化的本質是「讓優化器找到最短路徑」。持續收集 EXPLAIN、慢查詢日誌、Performance Schema 數據,建立「查詢模式-索引結構」映射知識庫,是 DBA 進階的核心功力。