分析下Mysql子查询的各种情况及执行计划

本文探讨了MySQL中子查询的执行计划和优化策略。首先,解释了子查询如何被拆分为两个步骤,先执行子查询获取单个值,然后在外层查询中使用。接着,介绍了当子查询条件依赖于外部表时导致的效率问题。对于`IN`子查询,文章指出MySQL会创建物化表并优化查询,尤其是当物化表较小且外部表较大时,会反向扫描物化表来提高效率。
摘要由CSDN通过智能技术生成

前言

之前已经学习了单表查询语句和多表关联于的执行原理,也熟悉了在生成具体执行计划的时候,是如何根据成本计算去选择最优执行计划的,今天再来分析下Mysql子查询的各种情况及执行计划

sql场景举例

(一)select * from t1 where x1 = (select x1 from t2 where id =xxx)

这个sql语句执行的时候,其实会被拆分为两部分,第一个步骤就是先执行子查询,也即是 select x1 from t2 where id =xxx,,然后直接根据主键定位出一条数据的x1字段的值,接着再执行 select * from t1 where x1 = 子查询的结果集,而这个过程其实和之前单表查询的方式是一样的。

select * from t1 where x1 = (select x1 from t2 where t1.x2 =t2.x2)

这种情况下可以看到子查询里的where条件依赖于t1表的字段值,所以这种查询就会效率很低下,它需要遍历t1表的每一条数据,对每一条数据取出x2字段的值,放到子查询里去执行,找出t2表的某条数据的x1字段的值,再放到外层去判断,是否符合跟t1表的x1字段匹配

select * from t1 where x1 in (select x2 from t2 where x3 =xxx)

针对于这种带in的子查询可能会一开始想当然的以为先执行子查询,然后在针对t1表进行全表扫描。判断每一条数据是否在这个子查询的结果集里,但是这种方式的效率实在是太低了,

所以mysql本身会对这样的sql做优化,即先执行子查询,把查询到的数据都放到一个临时表里,也可以叫做物化表,意思就是把这个中间结果集做物化。这个物化表可能会基于memory存储引擎通过内存存放,如果结果集太大,那么可能采用普通的b+树聚簇索引的方式放到磁盘里面,但是无论如何,这个物化表都会建立索引,即这波中间数据写入物化表是有索引的

那么紧接着是不是全局扫描t1表然后对每条数据都去物化表里根据索引快速查找是否在物化表里呢?

其实这里还可以优化就是说,假设t1表有50万条数据,而物化表只有500条数据,那么此时完全可以改成全表扫描物化表,然后对每一条数据的值都去t1表根据x1这个字段的索引进行查找,查找物化表的这个值是否在t1表的x1索引树里,如果在的话那么就符合条件,所以基于in语句的子查询方式,会按照上述进行优化

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值