SELECT * FROM t1 ORDER BY key_part1, key_part2...; SELECT * FROM t1 WHERE key_part1 = const ORDER 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; SELECT * FROM t1 WHERE key_part1 > const ORDER BY key_part1 ASC; SELECT * FROM t1 WHERE key_part1 < const ORDER BY key_part1 DESC; SELECT * FROM t1 WHERE key_part1 = const1 AND key_part2 > const2 ORDER BY key_part2;
ORDER BY key1, key2WHERE key2=const ORDER BY key_part2ORDER BY key_part1 DESC, key_part2 ASCWHERE key2=const ORDER BY key1核心鐵律:一條 SQL 不能同時使用兩個索引,需建立聯合索引。
sort_buffer_size、read_rnd_buffer_size。ORDER BY 列,消除 Filesort。SELECT * FROM a ORDER BY subject_code; -- 不用索引 SELECT id FROM a ORDER BY subject_code; -- 用索引 SELECT subject_code FROM a ORDER BY subject_code; -- 用索引 SELECT * FROM a WHERE subject_code = XX ORDER BY subject_code; -- 用索引
InnoDB 二級索引存 (subject_code, PK)。
SELECT * 若走二級索引排序,需按索引順序回主鍵查詢,隨機 IO 成本高於 Filesort,優化器選擇全表掃描 + Filesort。
SELECT id 或 SELECT subject_code 只需掃描二級索引(覆蓋索引),無回表,極快。
-- 原查詢:深分頁掃描大量行再丟棄 SELECT * FROM payment ORDER BY rental_id LIMIT 100,10; -- 方案一:子查詢覆蓋索引定位主鍵,再回表 SELECT * FROM `XXX` AS x INNER JOIN (SELECT id FROM `XXX` ORDER BY id DESC LIMIT M,N) AS t USING (id); -- 方案二:BETWEEN ... AND(需連續 ID,適用場景窄) -- 方案三:業務協作,前端傳 last_page_record,下一頁直接範圍查找
子查詢利用覆蓋索引無需回表即可定位主鍵,再 JOIN 回表取數據,大幅降低 IO。