按城市和天聚合订单,explain 的 Extra 是 Using temporary; Using filesort,tmpdir 下出现 8G 的临时文件,查询跑了 47 秒。日志里能对上时间点,这种反而好排。
group by 的列和索引顺序对不上时,数据库要先建临时表把行放进去再聚合,内存放不下就落磁盘。临时表上没有索引,去重和排序都退化成扫描。这一点先确认清楚,后面就不用反复试。
ALTER TABLE orders ADD INDEX idx_city_dt (city, dt); EXPLAIN SELECT city, dt, COUNT(*) FROM orders GROUP BY city, dt;
围绕「group by 临时表」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。
报错里带路径的,先去看那个路径在不在、权限对不对。同一份配置存在多处的,先确认改的是被加载的那一份。
处理上按这个顺序:建 (city, dt) 联合索引 让分组顺着索引顺序走;确认 group by 的列顺序和索引前缀一致;减少 select 里非聚合的列 降低临时表宽度;先解决走索引的问题 再去调临时表内存参数。
结果对不对很好判断,Extra 里 Using temporary 消失 查询从 47 秒降到 2 秒以内 临时目录不再增长。
