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

 而 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

在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()需要查询数据库,我们都知道查询数据库所消耗的性能更高,而内存比较很快。   

你可能感兴趣的:(mysql,数据库)