5分钟了解MySQL5.7union all用法的黑科技

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:

union all在MySQL5.6下的表现

Part1:MySQL5.6.25

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[root@HE1 ~] # mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection  id  is 2
Server version: 5.6.25-log MySQL Community Server (GPL)
Copyright (c) 2000, 2015, Oracle and /or  its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and /or  its
affiliates. Other names may be trademarks of their respective
owners.
Type  'help;'  or  '\h'  for  help. Type  '\c'  to  clear  the current input statement.
mysql>  select  version();
+------------+
| version()  |
+------------+
| 5.6.25-log |
+------------+
1 row  in  set  (0.26 sec)
   
mysql> explain ( select  id  from helei order by  id ) union all ( select  id  from t where  id =0 order by  id );
+----+--------------+------------+-------+---------------+--------+---------+------+------+-----------------+
id  | select_type  | table      |  type   | possible_keys | key    | key_len | ref  | rows | Extra           |
+----+--------------+------------+-------+---------------+--------+---------+------+------+-----------------+
|  1 | PRIMARY      | helei      | index | NULL          | idx_c1 | 4       | NULL | 5219 | Using index     |
|  2 | UNION        | t          | ALL   | NULL          | NULL   | NULL    | NULL |    1 | Using where     |
| NULL | UNION RESULT | <union1,2> | ALL   | NULL          | NULL   | NULL    | NULL | NULL | Using temporary |
+----+--------------+------------+-------+---------------+--------+---------+------+------+-----------------+
3 rows  in  set  (0.00 sec)

可以看出,在MySQL5.6版本中,执行结果如下图所示:

wKioL1f8bZvhzEMaAAFulp6pefo997.jpg

从执行计划来看,是把helei表的查询结果和t表的查询结果合并在了一张临时表里,然后输出给客户端。


union all在MySQL5.7/MariaDB10.1下的表现

Part1:MySQL5.7.15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@HE1 ~]# mysql -uroot -p
Enter  password
Welcome  to  the MySQL monitor.  Commands  end  with  or  \g.
Your MySQL  connection  id  is  8
Server version: 5.7.15-log MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle  and / or  its affiliates.  All  rights reserved.
Oracle  is  a registered trademark  of  Oracle Corporation  and / or  its
affiliates. Other names may be trademarks  of  their respective
owners.
Type  'help;'  or  '\h'  for  help. Type  '\c'  to  clear the  current  input statement.
mysql>  select  version();
+ ------------+
| version()  |
+ ------------+
| 5.7.15-log |
+ ------------+
1 row  in  set  (0.00 sec)、
mysql> explain ( select  id  from  helei  order  by  id)  union  all  ( select  id  from  where  id=0  order  by  id);
+ ----+-------------+-------+------------+-------+---------------+--------+---------+------+------+----------+-------------+
| id | select_type |  table  | partitions | type  | possible_keys |  key     | key_len | ref  |  rows  | filtered | Extra       |
+ ----+-------------+-------+------------+-------+---------------+--------+---------+------+------+----------+-------------+
|  1 |  PRIMARY      | helei |  NULL        index  NULL           | idx_c1 | 4       |  NULL  | 5212 |   100.00 | Using  index  |
|  2 |  UNION        | t     |  NULL        ALL    NULL           NULL    NULL     NULL  |    1 |   100.00 | Using  where  |
+ ----+-------------+-------+------------+-------+---------------+--------+---------+------+------+----------+-------------+
rows  in  set , 1 warning (0.00 sec)

可以看出,在MySQL5.7版本中,执行结果如下图所示:

wKiom1f8bijj3fJiAAF48HG3WPQ918.jpg




Part2:MariaDB10.1.16

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@HE3 ~]# /usr/ local /mariadb/bin/mysql -uroot -S /tmp/mariadb.sock 
Welcome  to  the MariaDB monitor.  Commands  end  with  or  \g.
Your MariaDB  connection  id  is  7
Server version: 10.1.16-MariaDB MariaDB Server
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab  and  others.
Type  'help;'  or  '\h'  for  help. Type  '\c'  to  clear the  current  input statement.
MariaDB [(none)]>
MariaDB [helei]> explain ( select  id  from  helei  order  by  id)  union  all  ( select  id  from  where  id=0  order  by  id);
+ ------+-------------+-------+-------+---------------+--------+---------+------+------+-------------+
| id   | select_type |  table  | type  | possible_keys |  key     | key_len | ref  |  rows  | Extra       |
+ ------+-------------+-------+-------+---------------+--------+---------+------+------+-------------+
|    1 |  PRIMARY      | helei |  index  NULL           | idx_c1 | 4       |  NULL  | 5198 | Using  index  |
|    2 |  UNION        | t     |  ALL    NULL           NULL    NULL     NULL  |    1 | Using  where  |
+ ------+-------------+-------+-------+---------------+--------+---------+------+------+-------------+
rows  in  set  (0.00 sec)

可以看出在MariaDB10.1中,执行结果如下图所示:

wKioL1f8bmmwi9GLAAFbMJCN0uU554.jpg

从执行结果看,无论是MySQL5.7还是MariaDB10.1,都没有创建临时表,按照顺序,helei表的查询结果首先输出到客户端,然后t表的查询结果再输出到客户端。


本文中的优化只针对union all,对union和在最外层使用order by无效。如下图是所示:

wKiom1f8boazPx35AAKnKQS1Ig4776.jpg




——总结——

在MySQL5.7/MariaDB10.1中,union all不再创建临时表,这样在联合查询时会减少I/O开销,在MySQL5.5/5.6中则不具备这一特性。由于笔者的水平有限,编写时间也很仓促,文中难免会出现一些错误或者不准确的地方,不妥之处恳请读者批评指正。


 本文转自 dbapower 51CTO博客,原文链接:http://blog.51cto.com/suifu/1860575,如需转载请自行联系原作者


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
关系型数据库 MySQL 索引
mysql中EXISTS用法注意点
mysql中EXISTS用法注意点
|
10天前
|
存储 SQL 关系型数据库
mysql用法
mysql用法
26 4
|
27天前
|
存储 自然语言处理 关系型数据库
MySQL的match用法说明
MySQL的match用法说明
25 4
|
1月前
|
SQL 关系型数据库 MySQL
MySQL的用法
MySQL的用法
39 1
|
2月前
|
存储 关系型数据库 MySQL
mysql中的left join、right join 、inner join的详细用法
【8月更文挑战第16天】在MySQL中,`INNER JOIN`、`LEFT JOIN`与`RIGHT JOIN`用于连接多表。`INNER JOIN`仅返回两表中匹配的行;`LEFT JOIN`保证左表所有行出现于结果中,右表无匹配时以NULL填充;`RIGHT JOIN`则相反,保证右表所有行出现于结果中。例如,查询学生及其成绩时,`INNER JOIN`仅显示有成绩的学生;`LEFT JOIN`显示所有学生及他们对应的成绩,无成绩者成绩列为空;`RIGHT JOIN`显示所有成绩及对应学生信息,无学生信息的成绩条目则为空。
|
1月前
|
存储 自然语言处理 关系型数据库
全文索引MySQL的match用法是什么?
【9月更文挑战第2天】全文索引MySQL的match用法是什么?
48 0
|
3月前
|
存储 JSON 关系型数据库
mysql中find_in_set()函数用法详解及增强函数
总结而言,`FIND_IN_SET()`是MySQL中处理由逗号分隔的字符串列表的一种便捷方法,尤其适用于列表相对较短且不经常更改的场景。然而,对于更为复杂的需要高性能和可扩展性的数据库设计,它可能不是最优选择,应考虑使用更加正规化的数据库结构。
277 2
mysql中find_in_set()函数用法详解及增强函数
|
3月前
|
关系型数据库 MySQL 数据库
MySQL:union all与union区别详解
MySQL:union all与union区别详解
|
4月前
|
关系型数据库 MySQL
MySQL中CASE WHEN用法总结
MySQL中CASE WHEN用法总结
|
4月前
|
存储 关系型数据库 MySQL
mysql mysqldump用法详解
mysql mysqldump用法详解