




能,但需满足索引最左前缀、排序方向一致且无函数干扰;通过EXPLAIN看Extra是否含Using filesort来判断,覆盖索引和游标分页可优化性能。
能,但不是所有 ORDER BY 都走索引。MySQL 只有在满足「索引最左前缀 + 排序方向一致 + 无函数/表达式干扰」时,才可能利用索引避免文件排序(Using filesort)。比如表有联合索引 INDEX (a, b),那么 ORDER BY a, b 或 ORDER BY a 可走索引;但 ORDER BY b 或 ORDER BY a DESC, b ASC(混合方向)通常不行。
用 EXPLAIN 查看 Extra 列:
Usin
g filesort → 没走索引排序,MySQL 在内存或磁盘做二次排序Using filesort,且 key 列显示用了某个索引 → 排序由索引天然有序性完成type 是 index 或 range,也不代表排序走了索引——关键还是看 Extra
以下情况会让 ORDER BY 强制退化为 filesort:
SELECT * + ORDER BY 非覆盖索引字段 → 回表后无法保持顺序,必须再排序WHERE 条件用了非最左前缀字段,比如索引是 (a, b, c),却写 WHERE b = 1 ORDER BY c
ORDER BY RAND()、ORDER BY UPPER(name) 等带函数的表达式 → 索引值不匹配原始列内容ORDER BY 字段来自被驱动表 → 优化器常放弃索引排序绕过思路:优先让 SELECT 字段和 ORDER BY 字段都落在同一覆盖索引中;必要时拆分查询,或用主键分页替代 LIMIT offset, size。
这是高并发分页的性能关键点。如果 ORDER BY id LIMIT 10 走了索引,但 ORDER BY id LIMIT 10000, 10 依然要扫描前 10000 行。
WHERE id > ? ORDER BY id LIMIT 10,配合上一页末尾 id 值SELECT *:只查必需字段,减少回表和排序开销CREATE INDEX idx_sort_status_ctime ON t (status, ctime DESC)
真正卡顿的往往不是排序本身,而是排序前的数据集太大——先用 WHERE 尽量缩小结果集,再考虑排序是否能走索引。