利用索引有序性,優化器沿索引順序掃描,掃滿 LIMIT 行即停止,避免全表排序(Using filesort)。
SELECT * FROM test_order_desc WHERE END_TIME > NOW() ORDER BY GMT_CREATE DESC, count_num DESC LIMIT 12, 12;
ind_hot_endtime(end_time, count_num)ALTER TABLE test_order_desc ADD INDEX ind_gmt_create(gmt_create, count_num);
type=INDEX,rows=48(估算掃 48 行即得 12 行)SELECT b.*, a.*, k.* FROM instance b LEFT JOIN image a ON b.image_id = a.image_id LEFT JOIN key_pair k ON b.key_pair_id = k.key_pair_id LEFT JOIN region_alias r_a ON r_a.region_no = b.region_no WHERE b.STATUS IN (1,8) AND b.user_id = 21 AND r_a.big_region_no = 'regeion_xx' ORDER BY b.instance_no ASC LIMIT 37300, 50;
idx_uid_stat_inid(user_id, status, instance_no)STATUS IN (1,8) 導致無法用 instance_no 排序,觸發 filesortALTER TABLE instance ADD INDEX ind_user_id(user_id, instance_no); -- 需 FORCE INDEX(ind_user_id) 才會用上
| 場景 | 索引設計建議 | 注意事項 |
|---|---|---|
| WHERE 篩選 + ORDER BY + LIMIT | (篩選欄位, 排序欄位) | 篩選選擇性高時優化器可能仍選篩選索引 |
| JOIN + ORDER BY 驅動表欄位 + LIMIT | 驅動表(關聯鍵, 排序欄位) | 常需 FORCE INDEX 或 STRAIGHT_JOIN 輔助 |
| 混合 ASC/DESC | MySQL 8.0+ 支援降序索引 | 舊版本需統一排序方向或應用層反轉 |
關鍵判斷:篩選選擇性高 → 排序成本低 → filesort 可接受;選擇性低 → 索引掃描 + LIMIT 極優。