标准答案
- GROUP BY 需要把相同键归并,DISTINCT 本质上也需要去重,ORDER BY 需要按目标键排列。
- 若过滤条件、分组键和排序键与同一索引顺序兼容,数据库可以减少额外排序或临时结构。
- 应先用 WHERE 缩小输入,再聚合和排序;HAVING 不应承担本可前置的普通行过滤。
- 只保留必要列,宽文本和 JSON 字段进入排序或临时表会显著增加内存与磁盘压力。
- 对于重复使用的大聚合,考虑汇总表、异步预计算或按时间分区,而不是每次请求扫描全量明细。
题目解析
看到临时表或 filesort 不能直接判定 SQL 有问题。几十条数据上的内存排序很便宜;真正危险的是高频查询对百万行宽记录做分组排序,并把临时数据溢写到磁盘。
优化顺序通常是先减少行数,再利用合适索引,最后才考虑改变报表形态。很多统计页面更适合读取按日汇总的数据,而不是在用户每次刷新时临时计算所有历史明细。
常见误区
- 用 DISTINCT 掩盖错误 JOIN 产生的重复,既慢又可能掩盖业务数据问题。
- 为了消除一次小排序创建大量宽索引,反而拖慢所有写入。