Appearance
ORDER BY、GROUP BY 为什么容易慢
先说结论
ORDER BY、GROUP BY慢,很多时候不是 SQL 写错,而是没走上合适索引- 一旦需要额外排序、临时表或大范围扫描,成本就会明显上来
- 真正排查时,先看扫描范围,再看排序和分组能不能在索引层解决
一、为什么这两类操作天然更重
因为它们都不是“取出数据就结束”。
ORDER BY需要确定顺序GROUP BY需要聚合归并
如果数据库不能直接沿着索引顺序把结果吐出来,就通常要额外做:
- 排序
- 建临时表
- 聚合中间结果
这也是为什么很多查询条件不算复杂,但一加排序或分组就明显变慢。
二、ORDER BY 最常慢在哪
1. 排序列没命中索引顺序
如果 where 条件和 order by 的列组合与索引不匹配,数据库往往只能先筛再排,代价会很高。
2. 返回行数太多
哪怕排序逻辑没问题,结果集本身很大时,排序成本也会明显上升。
3. 排序方向和索引顺序不匹配
有些场景即使有索引,也未必能完全利用。
三、GROUP BY 最常慢在哪
1. 先扫很多,再聚合
如果过滤条件不够收敛,分组前就已经读了太多数据,后面的聚合自然会重。
2. 分组字段基数高
分组值越分散,中间结果通常越大,内存和临时表压力也越明显。
3. 还叠加排序
很多 SQL 不只是 GROUP BY,还会再加:
ORDER BY count(*) descLIMIT
这类语句很容易把“聚合 + 排序”两个重操作叠起来。
四、排查时优先看什么
更实用的顺序通常是:
- 先看 where 条件是否已经收住扫描范围。
- 再看排序或分组字段是否有合适索引支持。
- 再看是不是出现了临时表、文件排序之类的额外成本。
- 最后再决定是改 SQL、补索引,还是改查询思路。
很多时候不是数据库扛不住,而是让它做了本来就不适合在线实时做的大排序和大聚合。
五、最容易踩的坑
1. 以为有索引就一定不会排序
索引有没有建,和能不能按当前条件、当前顺序真正用上,是两回事。
2. 先把结果全查出来再排序分页
这类写法在数据一多时,性能会很快变差。
3. 把统计类 GROUP BY 直接压在主库热点表上
如果是高频看板、报表类需求,很多时候更适合走汇总表、缓存或离线链路。
总结
ORDER BY、GROUP BY 容易慢,不是因为它们“特殊”,而是因为一旦索引不匹配,就会触发额外排序、聚合和临时表开销。排查时先看扫描范围,再看索引能不能承接排序和分组,比上来就调参数更有效。