實測兩張表(menu_employee MyISAM、l_insertlogs InnoDB),對比 FORCE INDEX 指定聯合索引 vs 單列索引在 WHERE ... AND ... ORDER BY 場景下的執行計劃差異。結論:聯合索引不總是優於單列,列序與查詢模式必須精準對齊,否則反而觸發 filesort。
-- 表結構
KEY `x` (`employee_id`, `employee_pid`) USING BTREE
-- 查詢
EXPLAIN SELECT employee_name
FROM menu_employee FORCE INDEX (x)
WHERE employee_id > 3 AND employee_pid > 20
ORDER BY employee_pid;
Using index; Using filesort —— 命中索引但仍需排序!Using index —— 無 filesort,直接有序輸出!Using index; Using filesort —— 需排序。原因:聯合索引按 (employee_id, employee_pid) 排序,WHERE employee_id > 3 為範圍條件,導致 employee_pid 在索引中不再有序,必須 filesort。單列 employee_pid 索引天然有序,完美匹配 ORDER BY employee_pid。
-- 表結構
KEY `x` (`Counts`, `ID`) USING BTREE
-- 查詢
EXPLAIN SELECT TablesName
FROM l_insertlogs FORCE INDEX (x)
WHERE ID BETWEEN 100 AND 500 AND Counts > 14
ORDER BY Counts;
(Counts, ID):Using where; Using filesortID (PK):Using where; Using filesortCounts:Using index —— 唯一無 filesort 方案!原因:ORDER BY Counts 需 Counts 有序。聯合索引首列為 Counts,但 WHERE ID BETWEEN ... 為範圍掃描,破壞了 Counts 的有序性。單列 Counts 索引直接有序輸出。
| 場景 | 最佳索引 | 關鍵點 |
|---|---|---|
| WHERE 等值 + ORDER BY 同列 | 單列索引 (ORDER BY 列) | 範圍條件破壞聯合索引有序性 |
| WHERE 等值前綴 + ORDER BY 後綴 | 聯合索引 (WHERE列, ORDER BY列) | 等值不破壞有序,後綴保持有序 |
| WHERE 範圍 + ORDER BY 另一列 | 單列索引 (ORDER BY 列) | 聯合索引首列範圍 → 後綴無序 |
| 純 ORDER BY 無 WHERE | 單列索引 (ORDER BY 列) | 最簡直接 |