资讯专栏INFORMATION COLUMN

MySQL5.6子查询优化总结

DevTTL / 2148人阅读

摘要:所以在做多个子查询时需注意对子查询的合并。子查询展开对比逻优化后,将子查询展开的语句所以对嵌套的子查询,注意在逻辑上进行展开,将其和外表连接查询。

1、子查询合并不支持
mysql> explain select * from t1 where exists (select * from t2 where t2.a2>5) and exists (select * from t2 where t2.a2<10);
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | PRIMARY | t1 | ALL | NULL | NULL | NULL | NULL | 9867 | NULL |
| 3 | SUBQUERY | t2 | ALL | NULL | NULL | NULL | NULL | 100 | Using where |
| 2 | SUBQUERY | t2 | ALL | NULL | NULL | NULL | NULL | 100 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
3 rows in set (0.00 sec)

依然是两条子查询 没有合并成一条。
对比子查询逻辑优化后的语句:
mysql> explain select * from t1 where exists (select * from t2 where t2.a2>5 and t2.a2<10);
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | PRIMARY | t1 | ALL | NULL | NULL | NULL | NULL | 9867 | NULL |
| 2 | SUBQUERY | t2 | ALL | NULL | NULL | NULL | NULL | 100 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
2 rows in set (0.01 sec)
两个子查询合并成了一条。

所以在做多个子查询时需注意对子查询的合并。

2、子查询展开
mysql> explain select * from t1, (select * from t2 where t2.a2>10) v_t2 where t1.a1<10 and v_t2.a2<20;

| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 100 | Using where |
| 1 | PRIMARY | t1 | ALL | NULL | NULL | NULL | NULL | 9867 | Using where; Using join buffer (Block Nested Loop) |
| 2 | DERIVED | t2 | ALL | NULL | NULL | NULL | NULL | 100 | Using where |

3 rows in set (0.00 sec)

对比逻优化后,将子查询展开的语句:
mysql> explain select * from t1, t2 where t1.a1<10 and t2.a2<20;

| 1 | SIMPLE | t2 | ALL | NULL | NULL | NULL | NULL | 100 | Using where |
| 1 | SIMPLE | t1 | ALL | NULL | NULL | NULL | NULL | 9867 | Using where; Using join buffer (Block Nested Loop) |

2 rows in set (0.00 sec)
所以对嵌套的子查询,注意在逻辑上进行展开,将其和外表连接查询。

3、不支持对聚类子查询的消除

4、不支持对exists、not exists类型的子查询优化

5、支持对IN类型的子查询优化,但有些情况下优化不完全。
mysql> explain select b1 from t1 where t1.a1 in (select t2.a2 from t2 where t2.b2=10);
+----+--------------+-------------+------+---------------+------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------+-------------+------+---------------+------+---------+------+------+----------------------------------------------------+
| 1 | SIMPLE | | ALL | NULL | NULL | NULL | NULL | NULL | NULL |
| 1 | SIMPLE | t1 | ALL | NULL | NULL | NULL | NULL | 9867 | Using where; Using join buffer (Block Nested Loop) |
| 2 | MATERIALIZED | t2 | ALL | NULL | NULL | NULL | NULL | 100 | Using where |
+----+--------------+-------------+------+---------------+------+---------+------+------+----------------------------------------------------+
3 rows in set (0.00 sec)

上表说明对IN类型子查询做了一定优化,但是不完全,没有消除子查询。
对比优化后的语句:
mysql> explain select b1 from t1, t2 where t1.a1=t2.a2 and t2.b2=10;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------------+
| 1 | SIMPLE | t2 | ALL | NULL | NULL | NULL | NULL | 100 | Using where |
| 1 | SIMPLE | t1 | ALL | NULL | NULL | NULL | NULL | 9867 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------------+
2 rows in set (0.00 sec)

6、对于NOT IN类型子查询,同样支持物化的优化,但不支持子查询的消除。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/46374.html

相关文章

  • 面试前必须知道的MySQL命令【explain】

    摘要:前言只有光头才能变强刷面试题的时候,不知道你们有没有见过这两个命令和反正我就见过了之前虽然知道这两个命令大概什么意思,但一直没有去做笔记。读懂命令结果命令输出的结果有列包含一组数字,表示查询中执行子句或操作表的顺序。 前言 只有光头才能变强 刷面试题的时候,不知道你们有没有见过MySQL这两个命令:explain和profile(反正我就见过了).. 之前虽然知道这两个命令大概什么意思...

    Cc_2011 评论0 收藏0
  • 面试前必须知道的MySQL命令【explain】

    摘要:前言只有光头才能变强刷面试题的时候,不知道你们有没有见过这两个命令和反正我就见过了之前虽然知道这两个命令大概什么意思,但一直没有去做笔记。读懂命令结果命令输出的结果有列包含一组数字,表示查询中执行子句或操作表的顺序。 前言 只有光头才能变强 刷面试题的时候,不知道你们有没有见过MySQL这两个命令:explain和profile(反正我就见过了).. 之前虽然知道这两个命令大概什么意思...

    IamDLY 评论0 收藏0
  • 2018MySQL面试知识点整理

    摘要:查询子句多个字段,前可使用聚合函数,对查询后结果的筛选和后面的语法类似字段别名表别名子查询子查询结果作为父查询的表子查询子查询结果命名子查询作为字段使用子查询可以跨多个表隔离级别未提交读,可能产生脏读,不可重复读,幻读读已提交,可能产生不可 mysql 查询子句: group by 多个字段,group by 前可使用聚合函数, having: 对查询后结果的筛选 和where后...

    myshell 评论0 收藏0
  • 一次非常有意思的SQL优化经历:从30248.271s到0.001s

    摘要:总结嵌套子查询效率确实比较低可以将其优化成连接查询建立合适的索引学会分析执行计划,会对进行优化,所以分析执行计划很重要。 showImg(https://segmentfault.com/img/bVbspGO?w=1080&h=608); 本文来源 | toutiao.com/i6668275333034148356 作者 | Java技术架构 背景介绍 我用的数据库是mysql5...

    lieeps 评论0 收藏0
  • 一次非常有意思的SQL优化经历:从30248.271s到0.001s

    摘要:总结嵌套子查询效率确实比较低可以将其优化成连接查询建立合适的索引学会分析执行计划,会对进行优化,所以分析执行计划很重要。 showImg(https://segmentfault.com/img/bVbspGO?w=1080&h=608); 本文来源 | toutiao.com/i6668275333034148356 作者 | Java技术架构 背景介绍 我用的数据库是mysql5...

    wwq0327 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<