MySQL子查询辨析

 

一 明确IN/EXISTS的语义

1 “expression IN (subquery)”这样的形式,表示一个表达式变量在一个子查询中存在,其结果是布尔值,TRUE或FALSE.

如果subquery 的结果中有重复值,则只要这样的值存在一次,IN格式的子查询结果就为TRUE,所以我们可以把 subquery表意为 “DISTINCT subquery”.

所以,“expression IN (subquery)”这样的形式其实表达的就是半连接的语义.


2 “EXISTS (subquery)”这样的形式,表示在一个子查询中存在子查询指定的情况,其结果是布尔值,TRUE或FALSE.

如果subquery 的结果中有重复值,则只要这样的值存在一次,EXISTS格式的子查询结果就为TRUE,所以我们可以把 subquery表意为 “只要有一个存在就为TRUE”.

所以,“expression IN (subquery)”这样的形式其实表达的也是半连接的语义.


所以,优化器对IN/EXISTS类型的子查询,优化的首选思路就是转为半连接操作. 这点在MySQL中正是这样.


NOT IN/NOT EXISTS同理.


二 MySQL处理子查询的过程

MySQL子查询辨析 - 那海蓝蓝 - 那海蓝蓝的博客
 


主体过程: 实则分为2种情况

情况一:可优化,被优化为半连接

1 把子查询转为半连接语义,即上拉子查询为“semi join”操作. 这是子查询上拉技术,只是连接语义变为半连接的语义.

2 如果不能转为“semi join”操作,则转为“exists”谓词对应的操作.

不能转为“semi join”操作的条件是: 子查询和父查询中的表的个数之和超出了MySQL所能处理的多表连接的表数(表数是用宏表示的MAX_TABLES的值,最大是63)。所以这个情况通常情况下遇不到。

3 如果被优化为半连接,则后续使用代价估算模型,判断,是否可以再进一步用物化操作来优化半连接中的被连接的表。如果物化的代价低,则使用物化。

4 如果被优化为半连接,后续为半连接去重操做选择5种策略之一。

所以,以上都是归属于上拉子查询为“semi join”操作这种优化方式的(其他的优化方式,属于小的优化,最主要的优化是上拉子查询为“semi join”操作这种优化方式)。

情况二:不可优化

5 如果不能被优化为半连接,则会被标示为“subquery”,看到这个,意味着子查询没有被优化。

6 尽管一些子查询没有被使用上拉技术优化,但其中涉及的表,依然可以判断是否可以被物化优化。所以注意在使用“show warnings;”看到的结果中会有一些“<materialize>”和“materialized-subquery”的提示字样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值