子查询之ALL/ANY/SOME重写思路

算法逸影客
• 阅读 148

SOME与ANY的含义相同,且 =ANY 或 =SOME 都等价于IN
select emp_id from t1 where owner =ANY (select name from t2 where id=100);
select emp_id from t1 where owner =SOME (select name from t2 where id=100);
上面都等价于:
select emp_id from t1 where owner in (select name from t2 where id=100);

NOT IN 与 <>ALL的含义相同,但与<>ANY含义不同

对于ALL/ANY/SOME类子查询,条件是非等值比较,如果子查询中没有GROUP BY等聚集函数,可以用MIN/MAX做等价转换
根据ALL/ANY/SOME的不同,以及后面的大于,小于号的不同,又分为好多种情形,下面只列出一种
select emp_id from t1 where age >ALL (select age from t2);
等价于:
select emp_id from t1 where age >MAX (select age from t2);

以上参考:《数据库查询优化器的艺术》,P26

对于=ALL的子查询,且是非相关子查询,用EXISTS strategy方式优化
select * from t1 where t1.age =ALL (select age from t2 where t2.age=10)
t1.age为非空时。优化器利用exists strategy重写为:select * from t1 where (t1.age EXISTS (SELECT 1 FROM t2 where t2.age=10 AND t1.age=t2.age)
(P383-P384)
思考,这是优化器的行为,但是优化点在哪里?
这个问题,在官网时这么解释的:
Consider the following subquery comparison:

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

MySQL evaluates queries “from outside to inside.” That is, it first obtains the value of the outer expression outer_expr, and then runs the subquery and captures the rows that it produces.

A very useful optimization is to “inform” the subquery that the only rows of interest are those where the inner expression inner_expr is equal to outer_expr. This is done by pushing down an appropriate equality into the subquery's WHERE clause to make it more restrictive. The converted comparison looks like this:

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

After the conversion, MySQL can use the pushed-down equality to limit the number of rows it must examine to evaluate the subquery.

参考:
1.MySQL子查询---EXISTS优化策略辨析
2.Optimizing Subqueries with the EXISTS Strategy

点赞
收藏
评论区
推荐文章
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
凯特林 凯特林
4年前
JS - 用 for 循环实现常见的数组迭代方法
常见的数组迭代方法有很多种,比如some,filter,map等等,底层也都可以用for来实现,我们来康一康。somejsconstsome(arr,fn)for(leti0;i<arr.length;i)if(fn(arri,i,arr))re
源码中看到val.toString === Object.prototype.toString
在啃vue源码过程中看到:jsconsttoStringObject.prototype.toString/Convertavaluetoastringthatisactuallyrendered.将值转换为实际呈现的字符串/exportfunctiontoString(val:any):stringretu
Souleigh ✨ Souleigh ✨
4年前
TypeScript: 请停止使用 any
当我们开发TypeScript代码时,很可能会遇到any关键字。我们看到的大多数用法都表明我们正在处理TypeScript中的基本类型。在文档中我们可能会找到:(…)来不使用TypeScript或第3方库编写的代码的值。在这些情况下,我们可能要选择退出类型检查。为此,我们将这些值标记为any类型:什么是any因此any
Stella981 Stella981
3年前
Intellij Idea启动springboot报ClassNotFoundException
IntellijIdea版本为Ultimate2016.1,gradle版本为3.5,启动springboot报错java.lang.NoClassDefFoundError:org/springframework/boot/SpringApplicationatcom.some.fancy.name.Applicat
Stella981 Stella981
3年前
PostgreSQL数据库切割和组合字段函数
Postgresql里面内置了很多的实用函数,下面介绍下组合和切割函数环境:PostgreSQL9.1.2     CENTOS5.7final一.组合函数1.concata.语法介绍concat(str"any",str"any",...)
Stella981 Stella981
3年前
JavaScript Array some() 方法
JavaScriptArraysome()方法实例检测数组中是否有元素大于18:varages\3,10,18,20\;functioncheckAdult(age){   returnage18;}func
Stella981 Stella981
3年前
Consumer is not subscribed to any topics
产生该问题的原因主要是zookeeper中存在旧版本的kafkaconnecttopic信息,导致新版本的kafkaconnect启动异常:ERRORUnexpectedexceptioninThreadKafkaBasedLogWorkThreadconnectconfigs,5,main(org.a
Easter79 Easter79
3年前
TypeScript 实现Dictionary
1interfaceIDictionary{2add(key:string,value:any):void;3remove(key:string):void;4containsKey(key:string):boolean;5keys():
Easter79 Easter79
3年前
The Complete Guide To Rooting Any Android Phone
PhoneWhitsonGordon(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.lifehacker.com.au%2Fauthor%2Fwhitsongordon%2F)7April,20118:00AMShare(https://ww
Stella981 Stella981
3年前
Hibernate @Any 及 @ManyToAny 使用教程
前言最好的老师是google,不信你去试下百度一@Any(http://my.oschina.net/u/115936)的使用方法  场景:假设一个车辆类,它可以是个人或者公司拥有:@Entity
算法逸影客
算法逸影客
Lv1
春色满园关不住,一枝红杏出墙来。
文章
2
粉丝
0
获赞
0