MySQL 8.0开始Group by不再排序

如题所示,mysql 8.0 开始 group by 默认是没有排序的
那mysql 8.0 之前和 8.0 就有可能结果出现不同 需要警惕
查看版本信息 

[email protected]>[employees]>show variables like '%version%';
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| innodb_version          | 5.7.14                       |
| protocol_version        | 10                           |
| slave_type_conversions  |                              |
| tls_version             | TLSv1,TLSv1.1                |
| version                 | 5.7.14-log                   |
| version_comment         | MySQL Community Server (GPL) |
| version_compile_machine | x86_64                       |
| version_compile_os      | linux-glibc2.5               |
+-------------------------+------------------------------+


1234567891011121314151617
运行如下SQL
表信息 

[email protected]>[employees]>select * from t_group ;
+--------+---------+------------+------------+
| emp_no | dept_no | from_date  | to_date    |
+--------+---------+------------+------------+
|  22744 | d006    | 1986-12-01 | 9999-01-01 |
|  24007 | d005    | 1986-12-01 | 9999-01-01 |
|  30970 | d005    | 1986-12-01 | 2017-03-29 |
|  31112 | d002    | 1986-12-01 | 1993-12-10 |
|  40983 | d005    | 1986-12-01 | 9999-01-01 |
|  49554 | d008    | 1986-12-01 | 1992-05-27 |
|  48317 | d008    | 1986-12-01 | 1989-01-11 |
|  49667 | d007    | 1986-12-01 | 9999-01-01 |
|  50449 | d005    | 1986-12-01 | 9999-01-01 |
|  10004 | d004    | 1986-12-01 | 9999-01-01 |
+--------+---------+------------+------------+
10 rows in set (0.00 sec)

查看执行 计划  发现extra 部分含有 usisng fiesort 

[email protected]>[employees]>desc select dept_no ,count(*) from t_group group by dept_no ;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                           |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
|  1 | SIMPLE      | t_group | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   10 |   100.00 | Using temporary; Using filesort |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+---------------------------------+
1 row in set, 1 warning (0.00 sec)

运行结果 是按照 dept_no 排序 输出 

[email protected]>[employees]>select dept_no ,count(*) from t_group group by dept_no ;
+---------+----------+
| dept_no | count(*) |
+---------+----------+
| d002    |        1 |
| d004    |        1 |
| d005    |        4 |
| d006    |        1 |
| d007    |        1 |
| d008    |        2 |
+---------+----------+
6 rows in set (0.00 sec)


123456789101112131415161718192021222324252627282930313233343536373839404142434445
下面是8.0 版本
[email protected]>[test]>show variables like '%version%';
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| innodb_version          | 8.0.13                       |
| protocol_version        | 10                           |
| slave_type_conversions  |                              |
| tls_version             | TLSv1,TLSv1.1,TLSv1.2        |
| version                 | 8.0.13                       |
| version_comment         | MySQL Community Server - GPL |
| version_compile_machine | x86_64                       |
| version_compile_os      | linux-glibc2.12              |
| version_compile_zlib    | 1.2.11                       |
+-------------------------+------------------------------+


[email protected]>[test]>select * from t_group ;
+--------+---------+------------+------------+
| emp_no | dept_no | from_date  | to_date    |
+--------+---------+------------+------------+
|  22744 | d006    | 1986-12-01 | 9999-01-01 |
|  24007 | d005    | 1986-12-01 | 9999-01-01 |
|  30970 | d005    | 1986-12-01 | 2017-03-29 |
|  31112 | d002    | 1986-12-01 | 1993-12-10 |
|  40983 | d005    | 1986-12-01 | 9999-01-01 |
|  49554 | d008    | 1986-12-01 | 1992-05-27 |
|  48317 | d008    | 1986-12-01 | 1989-01-11 |
|  49667 | d007    | 1986-12-01 | 9999-01-01 |
|  50449 | d005    | 1986-12-01 | 9999-01-01 |
|  10004 | d004    | 1986-12-01 | 9999-01-01 |
+--------+---------+------------+------------+

1234567891011121314151617181920212223242526272829303132
运行相同的sql
执行 计划  可以看出 extra 部分 已经没有 using filesort 

[email protected]>[test]>desc select dept_no ,count(*) from t_group group by dept_no ;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra           |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-----------------+
|  1 | SIMPLE      | t_group | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   10 |   100.00 | Using temporary |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-----------------+
1 row in set, 1 warning (0.00 sec)

执行结果中 发现 不是按照 dept_no 排序 输出的

[email protected]>[test]>select dept_no ,count(*) from t_group group by dept_no ;
+---------+----------+
| dept_no | count(*) |
+---------+----------+
| d006    |        1 |
| d005    |        4 |
| d002    |        1 |
| d008    |        2 |
| d007    |        1 |
| d004    |        1 |
+---------+----------+
6 rows in set (0.00 sec)

12345678910111213141516171819202122232425
如果这种情况下 进行分页
5.7 版本
[email protected]>[employees]>select dept_no ,count(*) from t_group group by dept_no  limit 1;
+---------+----------+
| dept_no | count(*) |
+---------+----------+
| d002    |        1 |
+---------+----------+
1 row in set (0.00 sec)
1234567
8.0版本
[email protected]>[test]>select dept_no ,count(*) from t_group group by dept_no  limit 1;
+---------+----------+
| dept_no | count(*) |
+---------+----------+
| d006    |        1 |
+---------+----------+
1 row in set (0.00 sec)
1234567
可以发现 两个结果是 不一样的  ,原因就是8.0之前是group by  包含using filesort
而 8.0开始是 没有的
为了避免这种问题,8.0开始 除了索引替换排序的优化思路之外的相关排序我们必须使用order by来进行
5.7
[email protected]>[employees]>select dept_no ,count(*) from t_group group by dept_no order by dept_no limit 1;
+---------+----------+
| dept_no | count(*) |
+---------+----------+
| d002    |        1 |
+---------+----------+
1 row in set (0.00 sec)

8.0
[email protected]>[test]>select dept_no ,count(*) from t_group group by dept_no order by dept_no limit 1;
+---------+----------+
| dept_no | count(*) |
+---------+----------+
| d002    |        1 |
+---------+----------+
1 row in set (0.00 sec)
1234567891011121314151617
我是知数堂SQL 优化班老师~ ^^
--------------------- 
作者:骑龟的兔子2018 
来源:CSDN 
原文:https://blog.csdn.net/qidan3500/article/details/84563296 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/weixin_38383877/article/details/88121251
今日推荐