欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ORACLE中in语句与exists语句的区别

程序员文章站 2022-07-04 09:39:29
我看了这篇文章对于笛卡尔积的认识更深入了,感觉sql语句的执行过程和算法分析中的分析时间复杂度的过程很像。因此特意转载一下,感谢写作本文的大神。 select * from a where id i...

我看了这篇文章对于笛卡尔积的认识更深入了,感觉sql语句的执行过程和算法分析中的分析时间复杂度的过程很像。因此特意转载一下,感谢写作本文的大神。

select * from a

where id in(select id from b)

以上查询使用了in语句,in()只执行一次,它查出b表中的所有id字段并缓存起来.之后,检查a表的id是否与b表中的id相等,如果相等则将a表的记录加入结果集中,直到遍历完a表的所有记录.

它的查询过程类似于以下过程
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;
  }
 }
}
return resultset;
 

可以看出,当b表数据较大时不适合使用in(),因为它会b表数据全部遍历一次.

如:a表有10000条记录,b表有1000000条记录,那么最多有可能遍历10000*1000000次,效率很差.

再如:a表有10000条记录,b表有100条记录,那么最多有可能遍历10000*100次,遍历次数大大减少,效率大大提升.

结论:in()适合b表比a表数据小的情况

select a.* from a a

where exists(select 1 from b b where a.id=b.id)

以上查询使用了exists语句,exists()会执行a.length次,它并不缓存exists()结果集,因为exists()结果集的内容并不重要,重要的是结果集中是否有记录,如果有则返回true,没有则返回false.

它的查询过程类似于以下过程

list resultset=[];

array a=(select * from a)

for(int i=0;i < a.length;i++) {
  if(exists(a[i].id) { //执行select 1 from b b where b.id=a.id是否有记录返回
    resultset.add(a[i]);
   }
}

return resultset;

当b表比a表数据大时适合使用exists(),因为它没有那么遍历操作,只需要再执行一次查询就行.

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

结论:exists()适合b表比a表数据大的情况

当a表数据与b表数据一样大时,in与exists效率差不多,可任选一个使用.