0

0

mysql中GROUP BY与聚合函数的执行过程

P粉602998670

P粉602998670

发布时间:2026-02-01 08:10:02

|

337人浏览过

|

来源于php中文网

原创

GROUP BY 先完成分组再聚合,无索引时需临时表和文件排序;SELECT 中非分组非聚合列在 only_full_group_by 下报错;COUNT(*) 统计所有行,COUNT(col) 仅非 NULL 行;HAVING 在分组后过滤且不能用索引。

mysql中group by与聚合函数的执行过程

GROUP BY 是先分组再聚合,不是边扫边算

MySQL 执行 GROUP BY 时,并非逐行读取就立即调用 COUNT()SUM() 累加。它必须先完成完整的分组划分,才能对每个组独立计算聚合结果。这意味着:如果没索引支撑,MySQL 往往要走临时表 + 文件排序(Using temporary; Using filesort),尤其在大表上会明显变慢。

常见错误现象:EXPLAIN 显示 Extra 列含 Using temporary,且查询响应时间随数据量非线性增长。

  • 分组字段无索引 → 强制全表扫描 + 内存/磁盘临时表
  • SELECT 中出现未分组也未聚合的列(如 SELECT name, COUNT(*) FROM t GROUP BY dept)→ 在 sql_mode=only_full_group_by 下直接报错 ERROR 1055
  • 聚合函数参数含表达式(如 SUM(price * qty))→ 不影响分组逻辑,但可能拖慢单行计算速度

聚合函数对 NULL 的处理是默认忽略,不是报错或转 0

COUNT()SUM()AVG() 这些函数天然跳过 NULL 值,这是 SQL 标准行为,不是 MySQL 特有。比如 COUNT(col) 只统计非 NULL 行;SUM(col) 对全 NULL 组返回 NULL,不是 0

容易踩的坑:

  • COUNT(*)COUNT(col) 结果不同:前者统计所有行,后者只计非空值
  • AVG(col) 在整数列上返回 DECIMAL 类型,可能引发应用层类型不匹配(如 Go 的 int64 接收失败)
  • 想把空组补成 0?得靠 COALESCE(SUM(col), 0),不能依赖聚合函数自己“兜底”

GROUP BY 后 HAVING 比 WHERE 更晚执行,且能引用聚合结果

WHERE 过滤发生在分组前,操作的是原始行;HAVING 过滤发生在分组后,操作的是每组的聚合结果。所以 HAVING 能写 HAVING COUNT(*) > 10,而 WHERE 写这个会报错。

性能提示:

齐博B2B电子商务系统
齐博B2B电子商务系统

齐博B2B系统是一款基于PHP程序和Mysql数据库为基础的开源B2B行业门户电子商务网站建站系统, 系统代码完整、开源,功能全面,架构优秀,提供良好的用户体验、及管理平台,是目前搭建B2B行业门户网站最好的程序之一。齐博B2B具有的功能特点包括:通行证整合功能通过通行证的整合,可以与流行的PHPWIND论坛或Discuz论坛以及Ucenter中心等进行通讯,从而为用户提供更多的交流场所,增加网站

下载
  • 尽量把过滤条件往前推——能用 WHERE 就别用 HAVING,减少参与分组的行数
  • HAVING 条件无法利用索引,纯内存过滤,大数据量下慎用复杂表达式
  • HAVING 中用了非聚合字段(如 HAVING dept = 'tech'),MySQL 会允许(依赖 sql_mode),但语义模糊,应避免

ORDER BY 与 GROUP BY 共存时,排序字段必须在 SELECT 列表中或满足函数依赖

当语句同时含 GROUP BYORDER BY,比如:

SELECT dept, COUNT(*) c FROM emp GROUP BY dept ORDER BY c DESC;

这条合法,因为 cSELECT 列表中的别名,且由聚合生成;但下面这句在 only_full_group_by 下会失败:

SELECT dept, COUNT(*) FROM emp GROUP BY dept ORDER BY name;

因为 name 既没出现在 GROUP BY,也不是聚合结果,MySQL 无法确定每组该取哪个 name 来排序。

解决方式只有两个:

  • name 加进 GROUP BY(改变分组粒度)
  • 用聚合函数包裹,如 ORDER BY MAX(name)

函数依赖规则(MySQL 5.7+)允许某些情况绕过限制,比如 dept 是主键,name 是其依赖列,但这种隐式行为难维护,不建议依赖。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

771

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

329

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

350

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1324

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

362

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

901

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

581

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

425

2024.04.29

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

54

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 2万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 819人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号