news 2026/6/26 17:09:52

GROUP BY优化全解:如何写出既不丢数据又飞快的分组查询

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GROUP BY优化全解:如何写出既不丢数据又飞快的分组查询

大家好,我是小耶,写功课只是为了我踩过的坑,你们别再踩了!

前几周我们讲了执行计划、索引设计、COUNT优化、事务隔离级别,今天来聊聊一个日常开发中使用频率极高、但也最容易出问题的话题:​GROUP BY​。

某天凌晨1点,报表系统卡了半小时。执行计划里赫然写着:Using where; Using temporary; Using filesort。这三个词凑在一起,意味着MySQL在内存里建了张临时表,把3000万行数据一行行插进去,然后全表扫描排序,最后返回10行。

这不是SQL,这是CPU烤机程序。

很多人以为“GROUP BY不就是分个组吗”,但实际上它的执行流程远比表面复杂。今天我们从执行机制出发,把GROUP BY的性能陷阱一个一个拆开讲。

先搞清楚:GROUP BY到底在做什么?

执行一条GROUP BY查询时,数据库做了三件事:

  1. 排序​:把数据按分组字段排序。只有相同值的行挨在一起,才能分组统计。
  2. 分组​:遍历排序后的结果,遇到相同值累加,遇到新值新开分组。
  3. ​**(可选)再排序**​:如果还有ORDER BY,再做一次排序。

问题的核心在于​第一步——排序​。如果分组字段上没有合适的索引,MySQL无法直接按顺序遍历数据,就只能建一张临时表,把符合条件的行全插进去,对临时表做filesort,再遍历分组。3000万行数据,先写临时表、再全表排序、再遍历——每一步都在烧CPU和磁盘I/O。

Using temporary和Using filesort什么时候触发?

触发Using temporary的规则​:如果GROUP BY的列没有可用索引,MySQL就必须先排序才能分组,而排序需要空间,于是建临时表。

但“可用索引”比你以为的苛刻——不是有索引就行,索引列的顺序决定一切。比如order_time有索引但city没有,执行SELECT city, COUNT(*) FROM orders WHERE order_time >= '2026-04-01' GROUP BY city,虽然order_time可以过滤数据,但过滤后的数据按city分组时city没有索引,仍然会触发临时表。

触发Using filesort的规则​:当GROUP BY的结果需要排序(比如ORDER BY cnt DESC),且排序无法利用索引完成时,就会触发filesort。

索引优化的核心原则

GROUP BY优化的根本思路是让分组字段走索引,避免临时表和文件排序

原则一:GROUP BY列必须形成索引的最左前缀

MySQL使用索引进行GROUP BY时,分组列必须是某个索引的最左前缀。如果表上有索引(c1, c2, c3)GROUP BY c1, c2可以利用索引,但GROUP BY c2, c3不行——因为c2不是最左前缀。

原则二:索引顺序决定一切——WHERE条件中的范围查询是分水岭

当WHERE条件中包含范围查询(><BETWEEN)时,索引的使用会受到限制。如果WHERE中有范围条件,范围条件涉及的列必须放在索引的后面,GROUP BY列必须前置

举例:查询“2026年4月之后的订单,按城市分组统计订单数”:

sql

SELECT city, COUNT(*) FROM orders WHERE order_time >= '2026-04-01' GROUP BY city;

推荐索引:(city, order_time)—— GROUP BY列city在前,范围条件order_time在后。

如果把索引建为(order_time, city),虽然order_time能过滤数据,但过滤后的数据按city分组时,city不在索引的前缀位置,依然会触发临时表。

原则三:覆盖索引进一步提速

如果索引不仅包含GROUP BY列,还包含聚合函数需要的列,查询可以直接从索引返回结果,不需要回表。例如SELECT city, SUM(amount) FROM orders GROUP BY city,索引(city, amount)可以让MySQL直接从索引完成分组和聚合。

MySQL 8.0的两大优化

优化一:取消GROUP BY的隐式排序

在MySQL 5.7及之前,GROUP BY默认会按分组字段排序。如果不需要排序结果,可以添加ORDER BY NULL来消除排序开销。

MySQL 8.0取消了GROUP BY的隐式排序。如果确实需要排序,必须显式写ORDER BY。这避免了不必要的排序开销,是一个值得关注的性能优化点。

优化二:Loose Index Scan(松散索引扫描)

这是MySQL使用索引处理GROUP BY的最高效方式。当GROUP BY列是索引的最左前缀时,MySQL可以“松散地”扫描索引,跳过不属于当前组的数据,只读取每个组的第一个键值。

举例:表有索引(c1, c2, c3),查询GROUP BY c1, c2,Loose Index Scan只需要读取每个(c1, c2)组合的第一行,而不是扫描所有行。当没有WHERE条件时,扫描的行数等于分组数,远小于总行数。

大数据量下的近似分组

当数据量极大且业务允许误差时,可以考虑近似分组方案:

  • 采样估算​:对数据进行抽样(如WHERE id % 100 = 0),在样本上做GROUP BY,再按比例放大结果。适用于趋势分析、快速报表。
  • 预计算汇总表​:对于固定维度的分组统计(如每日、每小时的聚合),可以定时计算并存入汇总表,查询直接读汇总表。
  • 分区表优化​:在大数据量场景下,结合分区表设计可以进一步减少数据扫描范围。

GROUP BY + 窗口函数的组合运用

分组后计算占比、同比等场景,GROUP BY和窗口函数可以组合使用:

-- 计算每个城市订单数占总订单数的比例 SELECT city, COUNT(*) AS city_cnt, COUNT(*) / SUM(COUNT(*)) OVER () AS ratio FROM orders GROUP BY city;

窗口函数在分组后的结果集上计算,不需要二次聚合,比子查询写法更简洁高效。

总结

GROUP BY的性能问题,根源往往在​索引设计​。理解临时表和文件排序的触发条件,遵循“GROUP BY列前置、范围条件后置、覆盖索引收尾”的索引设计原则,再配合MySQL 8.0的Loose Index Scan和取消隐式排序等新特性,就能让分组查询从“CPU烤机程序”变成“秒级响应”。遇到大数据量且业务允许误差时,采样估算和预计算也是值得考虑的方案。

小耶在手,SQL 不愁

还有什么想了解的,欢迎留言!小耶一定知无不言言无不尽……我们下次见~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/26 17:09:43

[Android] Lynix v1.2.0 高级版 - AI无限生图,图生视频

[Android] Lynix v1.2.0 高级版 - AI无限生图&#xff0c;图生视频 链接&#xff1a;https://pan.xunlei.com/s/VOvweo0zM3BQwiEJeFl92akcA1?pwd3j8x# Lynix是一款强大的AI创意工作室应用&#xff0c;能够将您的想法和照片转化为令人惊叹的视觉效果。所有高级功能

作者头像 李华
网站建设 2026/6/26 17:08:38

树莓派USB摄像头应用指南:从fswebcam基础到自动化脚本

1. 项目概述&#xff1a;为什么选择USB摄像头而非专用摄像头模块&#xff1f;在树莓派生态里&#xff0c;专用摄像头模块&#xff08;如Camera Module 3&#xff09;几乎是“官方标配”&#xff0c;它通过CSI接口直连&#xff0c;能提供高画质和低延迟。但在我过去十多年的嵌入…

作者头像 李华
网站建设 2026/6/26 17:05:31

智能包装系统如何促进,才让企业提升竞争力?

智能包装系统这几年跑得很快&#xff0c;企业的日常运转也跟着变了不少。生产线不再总靠人盯着&#xff0c;节拍更稳&#xff0c;返工少了&#xff0c;仓库里堆着的半成品也没那么多。拿中科天工的设备来说&#xff0c;自动化做得比较实&#xff0c;成本压得住&#xff0c;现场…

作者头像 李华
网站建设 2026/6/26 17:05:08

河南GEO优化服务商口碑分析,专业度如何影响市场评价?

随着人工智能搜索的普及&#xff0c;GEO&#xff08;生成式引擎优化&#xff09;已成为企业数字营销的新战场。在河南市场&#xff0c;以河南算卓网络科技有限公司为代表的本地服务商&#xff0c;正凭借独特的技术深耕与本土化优势&#xff0c;逐步重塑行业口碑格局。本文将从行…

作者头像 李华
网站建设 2026/6/26 17:04:41

ESP8266点阵时钟DIY:硬件选型与软件开发全解析

1. 项目概述 这个基于ESP8266的多功能点阵时钟项目&#xff0c;是我在工作之余花了近一个月时间完成的DIY作品。作为一个嵌入式开发爱好者&#xff0c;我一直想制作一个既实用又有趣的电子时钟&#xff0c;它不仅要有精准的时间显示功能&#xff0c;还要能展示更多个性化信息。…

作者头像 李华
网站建设 2026/6/26 17:04:18

引力波数据分析:基线规范与残差增益计算的核心技术与实践

1. 从信号到发现&#xff1a;引力波数据分析的基石当两个黑洞在宇宙深处相互绕转、最终并合&#xff0c;它们会以光速向宇宙各处播撒时空的涟漪——这就是引力波。2015年&#xff0c;LIGO首次直接探测到引力波&#xff0c;开启了引力波天文学的新纪元。但很多人不知道&#xff…

作者头像 李华