文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

一篇文章了解MySQL的group by

2023-08-18 12:52

关注

本文章MySQL使用的是5.7,引擎使用的是innodb
2. 使用的表结构(t1),字段a上有一个索引,
在这里插入图片描述

group by的常规用法是配合聚合函数,利用分组信息进行统计,常见的是配合max等聚合函数筛选数据后分析,以及配合having进行筛选后过滤。
聚合函数

示例1: 查询t1表,按照字段b进行分组,并求出分组后b字段a的总和。

SELECT  MAX(a) from t1 GROUP BY b

实例2:查询t1表,按照字段b进行分组,拿到b<100的所有数据,求出a的总和。

SELECT  MAX(a) from t1 GROUP BY b HAVING b<100

where和having区别

where子句将单个行过滤到查询结果中,而having子句将分组过滤到查询结果中 having子句中使用的列名必须出现在group by子句列表中,或包括在聚集函数中。

having子句的条件运算至少包括一个聚集函数,否则可以把查询条件移到where字句中来过滤单个行(注意聚集函数不可以用在where子句中)


我们执行以下语句

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100

查看explain执行情况,由于b字段上没有索引,所以进行全表扫描。
在这里插入图片描述

Using temporary; 表示使用了临时表;
Using filesort ,表示需要排序。

由于字段b上没有索引,它的执行顺序是这样的

在MySQL当中排序有两种
第一种是 全字段排序 ,第二种是 rowid 排序。 具体可以通过我的这篇文章去了解一篇文章搞懂MySQL的order by


我们执行以下语句

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100

在上述中,由于b字段没有索引,索引MySQL默认会对此语句进行排序。相信你也看了我的一篇文章搞懂MySQL的order by这篇文章,也了解了MySQL什么时候会用全字段排序,什么时候用 rowid 排序。

1. 使用磁盘临时文件进行排序

在此语句中,优化器使用的是全字段排序,那么使用全字段排序会有哪些问题?
在全字段排序中,它是通过sort_buffer进行排序,定义如下。

sort_buffer_size:就是 MySQL 为排序开辟的内存(sort_buffer)的大小。如果要排序的数据量小于sort_buffer_size,排序就在内存中完成。但如果排序数据量太大,内存放不下,则不得不利用磁盘临时文件辅助排序。

假如我们如下SQL语句查出有1亿行,这时由于我们查询数据大小超过了定义的 临时排序文件( sort_buffer_size)的大小时,

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100000000

那么,这时就需要使用外部排序,外部排序一般使用归并排序算法。可以这么简单理解,MySQL 将需要排序的数据分成 n份,每一份单独排序后存在这些临时文件中。然后把这n个有序文件再合并成一个有序的大文件。由于分成的的临时文件很多,就会造成排序的性能很差。


2. 查询数据超过临时文件大小(tmp_table_size)

这个例子里由于临时表只有 100 行,内存可以放得下,因此全程只使用了内存临时表。但是,内存临时表的大小是有限制的,参数 tmp_table_size 就是控制这个内存大小的,默认是 16M。接下来我把tmp_table_size大小改成1kb。

假如我们如下SQL语句查出有1亿行,这时由于我们查询数据大小超过了定义的 临时文件( tmp_table_size)的大小时。

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100000000

那么,这时就会把内存临时表转成磁盘临时表(磁盘临时表默认使用的引擎是 InnoDB)。由于我们数据量很大,很可能这个查询需要的磁盘临时表就会占用大量的磁盘空间。


我们还是以这条SQL语句为准

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100

1. 如果你的需求并不需要对结果进行排序,那你可以在 SQL 语句末尾增加 order by null

explain SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100 ORDER BY null 

查看explain 结果在这里插入图片描述

Using temporary; 表示使用了临时表;


2. 可以对group by字段建立索引

众所周知,由于我们MySQL的InnoDB引擎使用的数据结构是B+树,而B+树相比于B树最显著的特征就是B+树叶子节点是一个有序的双向列表。既然他已经有序了,那么我们是不是可以直接不进行排序了。

我们执行以下SQL语句,并在字段b上建立索引

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100

查看explain执行情况,没有进行排序,没有使用临时文件
在这里插入图片描述

Using index;使用了覆盖索引。
由于字段b上有索引,它的执行顺序是这样的

在这里插入图片描述

执行流程:

因此当我们扫描到整个输入的数据结束,就可以拿到 group by 的结果,不需要临时表,也不需要再额外排序


3. group by字段无法建立索引时

如果可以通过加索引来完成 group by 逻辑就再好不过了。但是,如果碰上不适合创建索引的场景,我们还是要老老实实做排序的。那么,这时候的 group by 要怎么优化呢?

如果我们明明知道,一个 group by语句中需要放到临时表上的数据量特别大,却还是要按照“先放到内存临时表,插入一部分数据后,发现内存临时表不够用了再转成磁盘临时表”,这样看上去就有点儿傻。

我们执行以下SQL语句,并使用 SQL_BIG_RESULT(SQL_BIG_RESULT告诉mysql的分组语句必须使用磁盘临时表)

SELECT  SQL_BIG_RESULT b, count(*) as c from t1 GROUP BY b HAVING b<100

查看explain执行情况
在这里插入图片描述
Using filesort 表示需要排序。

执行流程:

在根据有序数组,得到数组里面的不同值,以及每个值的出现次数。


5. MySQL8.0之后版本的group by

我们还是以这条SQL语句为准(MySQL版本8.0.26)

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100

查看explain执行情况
在这里插入图片描述
Using temporary; 表示使用了临时表;

group by 在 MySQL5.7 版本会自动排序,但是在MySQL8 .0之后版本就去掉了自动排序功能。


6.总结

1.如果对 group by 语句的结果没有排序要求,要在语句后面加 order by null;

2.尽量让 group by 过程用上表的索引,确认方法是 explain 结果里没有 Using temporary 和 Using filesort;

3.如果 group by 需要统计的数据量不大,尽量只使用内存临时表;也可以通过适当调大 tmp_table_size 参数,来避免用到磁盘临时表;

4.如果数据量实在太大,使用 SQL_BIG_RESULT 这个提示,来告诉优化器直接使用排序算法得到 group by 的结果。

5.group by 在 MySQL5.7 版本会自动排序,但是在MySQL8 .0之后版本就去掉了排序功能。


在这里插入图片描述

今晚我支持总监,法国冲冲冲!!!

来源地址:https://blog.csdn.net/qq_48157004/article/details/128067845

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯