MySQL 可直接利用索引順序避免額外排序,條件是:未使用的索引部分與所有 ORDER BY 欄位皆包含在 WHERE 條件中。
SELECT * FROM t1 ORDER BY key_part1, key_part2, ...;
SELECT * FROM t1 WHERE key_part1 = constant ORDER BY key_part2;
SELECT * FROM t1 WHERE key_part1 = constant GROUP BY key_part2;
SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 DESC;
SELECT * FROM t1 WHERE key_part1 = 1 ORDER BY key_part1 DESC, key_part2 DESC;
| 情況 | 範例 | 說明 |
|---|---|---|
| ORDER BY 欄位來自不同索引 | ORDER BY key1, key2 | 索引無法合併排序 |
| 非連續索引部分排序 | WHERE key2=const ORDER BY key_part2 | 跳過 key_part1 導致索引不可用 |
| 混用 ASC/DESC | ORDER BY key_part1 DESC, key_part2 ASC | 方向不一致無法利用索引順序 |
| 搜尋索引與排序索引不同 | WHERE key2=const ORDER BY key1 | 需先檢索再排序 |
| 多表 JOIN 且 ORDER BY 欄位非來自第一個非 const 表 | — | EXPLAIN 中第一表 join_type 非 const |
| ORDER BY 與 GROUP BY 表達式不同 | — | 需額外排序 |
| 索引非按序儲存(HASH/HEAP 表) | — | 本身無序 |
執行 EXPLAIN SELECT ... ORDER BY ...,若 Extra 欄位顯示 Using filesort 表示未使用索引,需額外排序。
sort_buffer_size 導致更多 I/O,僅當額外欄位總長超過 max_length_for_sort_data 才啟用sort_buffer_sizeread_rnd_buffer_sizetmpdir 指向大空間專用檔案系統(多路徑循環分佈於不同實體磁碟)