MySQL优化之EXISTS解析
研究exists 这个函数,并不感觉⼀辈⼦也⽤不上,有时候其实就在不经意间就需要了!
exists ⽤于检查⼦查询是否⾄少会返回⼀⾏数据,该⼦查询实际上并不返回任何数据,⽽是返回值True或False
exists 指定⼀个⼦查询,检测 ⾏ 的存在。通常使⽤exists来做什么呢?可以使⽤exists来判断数据的存在与否,再进⼀步操作,⽽insert if not exists 可以⽤在不允许重复插⼊数据的地⽅。
通常使⽤情况会是两个表之间相互有关联,⽐如A表的某个字段是B表的某个字段,A表的某些内容会根据B表变动等。
并且和它相近的 in 函数也是有这样的作⽤,它们之间的区别就是 :
in 是做外表和内表通过hash 连接,先查询⼦表,再查询主表,不管⼦查询是否有数据,都对⼦查询进⾏全部匹配。
exists是外表做loop 循环,先主查询,再⼦查询,然后去⼦查询中匹配,如果匹配到就退出⼦查询返回true,将结果放到结果集。
select * from 外表 a where  id i n(select  相关id from 内表)  in的执⾏类似如下:
List resultSet=[];
Array A=(select * from A);
Array B=(select id from B);
for(int i=0;i<A.length;i++) {
for(int j=0;j<B.length;j++) {
if(A[i].id==B[j].id) {
resultSet.add(A[i]);
break;
}
}
resultset 遍历
}
return resultSet;
⽽ select a.* from 外表 a  where exists(select 1 from 内表 b where a.id=b.id) 的exists的执⾏语句如下:
#select * from T1 where exists (select NULL from T2 where T2.y=T1.x)
for cursor1 in (select * from T1) 
  loop 
  if (exists (select NULL from T2 where T2.y=cursor1.x)) 
  then 
  返回记录; 
  end if; 
end loop;
说真的,loop⽅式我有些看不懂,但是换成java代码就差不多了
List resultSet=[];
Array A=(select * from 外表 A)
for(int i=0;i<A.length;i++) {
if(exists(A[i].id) {    //执⾏select 1 from 内表 b where b.id=a.id是否有记录返回
resultSet.add(A[i]);
}
}
return resultSet;
在in()的执⾏中,是先执⾏内表得到结果集,再执⾏外表,外表会对所有的内表结果集匹配,也就是如果外表有100,内表有10000
就会执⾏100*10000次,所以在内表⽐较⼤的时候,不合适⽤in()⽅法,效率⽐较低。
⽽在exists ()的执⾏过程中,并没有对每⼀条内表的数据都进⾏查询,⽽是存在该条数据的时候会将结果集存起来,到最后的时候同⼀输出结果集。
设:外表A,内表B。
A表有10000条记录,B表有1000000条记录, 那么exists()会执⾏10000次去判断A表中的id是否与B表中的id相等。
A表有10000条记录,B表有100000000条记录,那么exists()还是执⾏10000次,因为它只执⾏A.length次,可见B表数据越多,越适合exists()发挥效果.
再如:A表有10000条记录,B表有100条记录,那么exists()还是执⾏10000次,还不如使⽤in()遍历10000*100次,因为in()是在内存⾥遍历⽐较,⽽exists()需要查询数据库,我们都知道查询数据库所消耗的性能更⾼,⽽内存⽐较很快。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。