MySQL - GROUP BY 隐式排序

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL - GROUP BY 隐式排序

image.png

MySQL中GROUP BY隐式排序是什么概念呢?其它RDBMS没有这样的概念。

我们先来看看官方文档的介绍:

官方文档MySQL 5.7 Reference Manual中的“.2.1.14 ORDER BY Optimization”章节有如下介绍:

GROUP BY implicitly sorts by default (that is, in the absence of ASC or DESC designators for GROUP BY columns). However, relying on implicit GROUP BY sorting (that is, sorting in the absence of ASC or DESC designators) or explicit sorting for GROUP BY (that is, by using explicit ASC or DESC designators for GROUP BY columns) is deprecated. To produce a given sort order, provide an ORDER BY clause.

默认情况下GROUP BY隐式排序(即缺少GROUP BY列的ASC或DESC指示符)。但是,不推荐依赖于隐式GROUP BY排序(即在没有ASC或DESC指示符的情况下排序)或GROUP BY的显式排序(即,通过对GROUP BY列使用显式ASC或DESC指示符)。要生成给定的排序 ORDER,请提供ORDER BY子句。

从MySQL 8.0开始,GROUP BY字段不再支持隐式排序。

官方文档MySQL 8.0 Reference Manual中“8.2.1.16 ORDER BY Optimization”章节有如下介绍:

Previously (MySQL 5.7 and lower), GROUP BY sorted implicitly under certain conditions. In MySQL 8.0, that no longer occurs, so specifying ORDER BY NULL at the end to suppress implicit sorting (as was done previously) is no longer necessary. However, query results may differ from previous MySQL versions. To produce a given sort order, provide an ORDER BY clause.

之前的MySQL 5.7以及更低版本,GROUP BY在某些情况下隐式排序。在MySQL 8.0中,不再发生这种情况,因此不再需要在末尾指定ORDER BY NULL来抑制隐式排序(如前所述)。但是,查询结果可能与以前的MySQL版本不同。要产生给定的排序顺序,请提供ORDER BY子句。

 

那么来看看MySQL的GROUP BY隐式排序(GROUP BY sorted implicitly)吧。我们用“Removal of implicit and explicit sorting for GROUP BY”这篇博客中的例子。

#下面实验环境为MySQL 5.6.41()

mysql>selectversion() fromdual; 
+------------+|version()  |+------------+|5.6.41-log|+------------+1rowinset (0.00sec)   
mysql>CREATETABLEt (idINTEGER,  cntINTEGER); 
QueryOK, 0rowsaffected (0.04sec)   
mysql>INSERTINTOtVALUES (4,1),(3,2),(1,4),(2,2),(1,1),(1,5),(2,6),(2,1),(1,3),(3,4),(4,5),(3,6); 
QueryOK, 12rowsaffected (0.00sec) 
Records: 12Duplicates: 0Warnings: 0

MySQL在这里隐式地对GROUP BY的结果进行排序(即在缺少GROUP BY列的ASC或DESC指示符的情况下)。

mysql>SELECTid, SUM(cnt) FROMtGROUPBYid; --GROUPBY隐式排序|id|SUM(cnt) |+------+----------+|1|13||2|9||3|12||4|6|+------+----------+4rowsinset (0.00sec) 

MySQL还支持使用GROUP BY进行显式排序(即通过对GROUP BY列使用显式ASC或DESC指示符)

mysql>SELECTid, SUM(cnt) FROMtGROUPBYidDESC;  --GROUPBY显式排序+------+----------++------+----------+|4|6||3|12||2|9||1|13|+------+----------+4rowsinset (0.00sec) 

从MySQL8.0开始,MySQL不再支持GROUP BY的隐式或显示排序,如下所示:

#下面实验环境为MySQL 8.0.18

mysql>selectversion(); 
+-----------+|version() |+-----------+|8.0.18|+-----------+1rowinset (0.00sec)   
mysql>CREATETABLEt (idINTEGER,  cntINTEGER); 
QueryOK, 0rowsaffected (0.39sec)   
mysql>INSERTINTOtVALUES (4,1),(3,2),(1,4),(2,2),(1,1),(1,5),(2,6),(2,1),(1,3),(3,4),(4,5),(3,6); 
QueryOK, 12rowsaffected (0.10sec) 
Records: 12Duplicates: 0Warnings: 0mysql>SELECTid, SUM(cnt) FROMtGROUPBYid; 
+------+----------+|id|SUM(cnt) |+------+----------+|4|6||3|12||1|13||2|9|+------+----------+4rowsinset (0.00sec) 
mysql>SELECTid, SUM(cnt) FROMtGROUPBYidDESC; 
ERROR1064 (42000): YouhaveanerrorinyourSQLsyntax; checkthemanualthatcorrespondstoyourMySQLserverversionfortherightsyntaxtousenear'DESC'atline1

如上所示,GROUP BY隐式排序不支持了,在MySQL 8.0中,上面测试例子是无序的。GROUP BY显示排序则直接报错。所以如果有数据库从MySQL 5.7或之前的版本,迁移升级到MySQL 8的话,就需要特别留意这个问题了。正确的做法应该是GROUP BY .. ORDER BY 这种操作。如下所示:

mysql>SELECTid, SUM(cnt) FROMtGROUPBYid->ORDERBYid; 
+------+----------+|id|SUM(cnt) |+------+----------+|1|13||2|9||3|12||4|6|+------+----------+4rowsinset (0.00sec) 
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
自然语言处理 关系型数据库 MySQL
如何在mysql数据库里进行文本的相似度排序?
【8月更文挑战第28天】如何在mysql数据库里进行文本的相似度排序?
227 62
|
26天前
|
算法 关系型数据库 MySQL
MySQL高级篇——排序、分组、分页优化
排序优化建议、案例验证、范围查询时索引字段选择、filesort调优、双路排序和单路排序、分组优化、带排序的深分页优化
MySQL高级篇——排序、分组、分页优化
|
1月前
|
自然语言处理 关系型数据库 MySQL
match如何在mysql数据库里进行文本的相似度排序?
【9月更文挑战第1天】match如何在mysql数据库里进行文本的相似度排序?
50 1
|
2月前
|
关系型数据库 MySQL 数据处理
Mysql关于同时使用Group by和Order by问题
总的来说,`GROUP BY`和 `ORDER BY`的合理使用和优化,可以在满足数据处理需求的同时,保证查询的性能。在实际应用中,应根据数据的特性和查询需求,合理设计索引和查询结构,以实现高效的数据处理。
266 1
|
2月前
|
SQL 关系型数据库 MySQL
MySQL】-DQL(基本、条件、分组、排序、分页)详细版
通过这些查询方法,你可以高效地检索、分析和组织MySQL数据库中的数据,以满足各种应用需求。实践中,理解这些SQL语句的基础知识以及它们如何组合起来进行复杂的数据操作是至关重要的。
29 1
|
2月前
|
SQL 关系型数据库 MySQL
在 MySQL 中使用 `GROUP BY` 子句
【8月更文挑战第12天】
58 1
|
2月前
|
算法 关系型数据库 MySQL
揭秘MySQL中的版本号排序:这个超级算法将颠覆你的排序世界!
【8月更文挑战第8天】在软件开发与数据管理中,正确排序版本号对软件更新及数据分析至关重要。因MySQL默认按字符串排序版本号,可能出现'1.20.0'在'1.10.0'之前的不合理情况。解决办法是将版本号各部分转换为整数后排序。例如,使用`SUBSTRING_INDEX`和`CAST`函数从`software`表的`version`字段提取并转换版本号,再按这些整数排序。这种方法可确保版本号按逻辑正确排序,适用于'major.minor.patch'格式的版本号。对于更复杂格式,需调整处理逻辑。掌握此技巧可有效应对版本号排序需求。
113 3
|
2月前
|
存储 关系型数据库 MySQL
MySQL中的DISTINCT与GROUP BY:效率之争与实战应用
【8月更文挑战第12天】在数据库查询优化中,DISTINCT和GROUP BY常常被用来去重或聚合数据,但它们在实现方式和性能表现上却各有千秋。本文将深入探讨两者在MySQL中的效率差异,结合工作学习中的实际案例,为您呈现一场技术干货分享。
261 0
|
3月前
|
关系型数据库 MySQL
MySQL 保姆级教程(三):排序检索数据
MySQL 保姆级教程(三):排序检索数据
|
23天前
|
NoSQL 关系型数据库 MySQL
微服务架构下的数据库选择:MySQL、PostgreSQL 还是 NoSQL?
在微服务架构中,数据库的选择至关重要。不同类型的数据库适用于不同的需求和场景。在本文章中,我们将深入探讨传统的关系型数据库(如 MySQL 和 PostgreSQL)与现代 NoSQL 数据库的优劣势,并分析在微服务架构下的最佳实践。