order by 未走索引需先用 explain 检查执行计划,关注 type 是否为 index/range、extra 是否含 using filesort;复合索引须满足最左前缀且顺序匹配 where 和 order by 字段;覆盖索引可避免回表和排序开销;mysql 5.7 不支持降序索引,混合方向排序易失效;大数据量分页宜用游标替代 limit 偏移。

ORDER BY 没走索引?先看执行计划
MySQL 或 PostgreSQL 里 ORDER BY 变慢,大概率不是语句写得不对,而是没命中索引。别急着加索引,先用 EXPLAIN 看真实执行路径——特别是 type 字段是否为 index 或 range,Extra 里有没有 Using filesort。出现后者就说明排序在内存或磁盘临时文件里做,性能已掉档。
-
ORDER BY字段必须和WHERE条件字段一起构成最左前缀索引,否则索引可能被忽略 - 复合索引顺序很重要:比如查询
WHERE status = 'active' ORDER BY created_at DESC,索引应建为(status, created_at),反过来就不行 - 如果
SELECT *返回大量字段,即使排序走了索引,回表开销也可能拖慢整体响应
ASC/DESC 混排时索引失效的常见情况
MySQL 8.0+ 支持降序索引,但老版本(如 5.7)对 ORDER BY a ASC, b DESC 这类混合方向排序,几乎无法利用普通 B-Tree 索引。PostgreSQL 虽支持 DESC 索引,但若查询中 WHERE 和 ORDER BY 方向不一致,仍可能退化。
- MySQL 5.7 及更早版本中,
ORDER BY x DESC无法使用(x)升序索引加速,必须显式建(x DESC)(但实际无效,本质不支持) - PostgreSQL 中
CREATE INDEX idx ON t (a ASC, b DESC)可用于ORDER BY a, b DESC,但不能用于ORDER BY a DESC, b ASC - 避免在分页场景(如
LIMIT 10000, 20)中依赖混合方向排序,偏移量越大,扫描越深
覆盖索引减少排序+回表开销
当 SELECT 字段全部包含在索引中,数据库可直接从索引树取数,不用回主键查找行数据。这对带 ORDER BY 的分页查询尤其有效——既省 IO,又让排序结果天然有序。
1、对ASP内核代码进行DLL封装,从而大大提高了用户的访问速度和安全性;2、采用后台生成HTML网页的格式,使程序访问速度得到进一步的提升;3、用户可发展下级会员并在下级购买商品时获得差额利润;4、全新模板选择功能;5、后台增加磁盘绑定功能;6、后台增加库存查询功能;7、后台增加财务统计功能;8、后台面值类型批量设定;9、后台财务曲线报表显示;10、完善订单功能;11、对所有传输的字符串进行安全
- 例如查询
SELECT id, title, updated_at FROM posts WHERE category_id = 123 ORDER BY updated_at DESC LIMIT 20,可建索引(category_id, updated_at DESC, id, title) - 注意字段顺序:过滤字段在前,排序字段紧随其后,查询字段放最后;否则索引无法用于过滤或排序
- 覆盖索引会增大索引体积,写入性能略降,高频更新表需权衡
小结果集用内存排序,大结果集考虑物化或游标分页
当 ORDER BY 数据量不大(比如几千行),sort_buffer_size 足够时,全在内存排完再取前 N 条最快。但一旦涉及百万级扫描+排序,Using filesort 就成了瓶颈,这时传统 LIMIT offset, size 分页会越来越慢。
- 把
sort_buffer_size设太大会挤占其他连接内存,建议单次设 2–4MB,按需调整 - 替代
LIMIT 100000, 20的更好做法是游标分页:记录上一页最后的updated_at和id,下一页查WHERE updated_at - 对实时性要求不高的报表类查询,可预计算排序结果到临时表或物化视图,避免每次重排
排序性能问题从来不是单点优化能解决的——索引结构、查询写法、分页模式、配置参数,四个地方只要一个没对齐,ORDER BY 就可能悄悄变慢。最容易被忽略的是:你以为加了索引就万事大吉,其实它根本没被选中。










