mysql exits优化_使用Exists策略优化子查询

8月 24, 2014 |

Nix.Huang

考虑下面的子查询:

outer_expr IN (SELECT inner_expr FROM ... WHERE subquery_where)

MySQL从外到内的处理查询语句,先获得外层表达式outer_expr的值,然后执行子查询最后获取它产生的行。

一个非常有用的优化师通知子查询,inner_expr= outer_expr的行才是我们关心的行,可以通过将一个合适的相等条件加入子查询的where从句,这个查询语句被转换为:

EXISTS (SELECT 1 FROM ... WHERE subquery_where AND outer_expr=inner_expr)

转换之后,MySQL在执行子查询的时候能使用推入的相等条件来限制需要检索的行。

更一般的,N个值的格式,一个返回N个值的子查询也进行一样的转换。如果oe_i 和 ie_i代表相应的外层和里层表达式,这种子查询格式为:

(oe_1, ..., oe_N) IN

(SELECT ie_1, ..., ie_N FROM ... WHERE subquery_where)

转换为:

EXISTS (SELECT 1 FROM ... WHERE subquery_where

AND oe_1 = ie_1

AND ...

AND oe_N = ie_N)

为了简单,接下来的讨论假设外层和内层都是单个值,前面讨论的转换是有限制条件的,只有当我们忽略NULL值才行,推入策略只有当满足下面的两个条件后才能生效:

outer_expr 和 inner_expr都不能为NULL

你也不需要区分子查询的NULL和FALSE,(如果子查询是WHERE从句的OR 或AND表达式的一部分,MySQL假设你不在意)。

当上述条件的一个或者都不满足时,优化变得复杂,假设outer_expr是一个非NULL值,但是子查询没有产生满足outer_expr = inner_expr的行,outer_expr IN (SELECT ...)就按照下面的规则求值:

·         NULL, 如果SELECT产生inner_expr = NULL任意行

·         FALSE, 如果SELECT仅产生非NULL或者没有任何输出。

这种情况, 使用outer_expr = inner_expr来查找行的方式不再有效,查找这样的行还是有必要的,但是如果没有找到,就要查找inner_expr is NULL的行,大致的讲,子查询能别转换成:

EXISTS (SELECT 1 FROM ... WHERE subquer

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值