记忆角落

  • {{ item.name }}
  • 首页
  • 关于
  • 归档
  • 邻居
  • 捐赠

关于oracle中in和exists的效率

  • 郭良俊只狗
  • 2018-12-20
  • 2

我又遇到了问题了...

当遇到数据量大但是又要考虑效率和资源消耗问题时,我还是会从查的效率去改善,然后再到程序,毕竟你load数据时间也过长的话,那么程序等待数据也是一部分吧?

以下总结都是扯淡,请勿相信..

前两天有一个开发java小程序的需求,需要到全量话单数据里面抽出某几款的数据,因为等待结果时间比较长,前前后后优化了几次...因为全量话单数据表一个表就上E数据..好了新手扯淡请不要相信。

emmm..说回正题吧。自从工作后一直听到老大们对我说尽量用exists不要用in,因为exists只判断存在而in需要对比值,所以exists比较快,然后和同事打赌还输过一杯奶茶(心疼)。但看了看网上的一些东西才发现这种比较需要分情况哒...
  • 使用in方式

  • 使用exists方式

  • 普通连表方式

1.使用in方式

select * from A where id in (select id from B)--使用in方式执行的过程相当于:
select * from A, ( select distinct id from B ) B where A.id = B.id;

2.使用exists方式

select * from A where exists(select B.id from B where B.id=A.id)--使用exists方式执行的过程相当于:
for x in ( select * from A )
loop
if ( exists ( select null from B where B.id = A.id )
then 
OUTPUT THE RECORD
end if
end loop

3.普通连表方式

select A.*,B.* from A,B where A.id = B.id --普通连表方式使用笛卡尔乘积
具体使用时到底选择哪一个,主要需要考虑查询效率问题:
第一条语句使用了A表的索引;
第二条语句使用了B表的索引;
第三条语句同时使用了A表、B表的索引;

如果A、B表的数据量不大,那么这三个语句执行效率几乎无差别;
如果A表数据量大,B表小,显然第一条语句效率更高,反之,则第二条语句效率更高;
第三条语句尽管同时使用了A表、B表的索引,单扫描次数是笛卡尔乘积,效率最差。(hive上我是这样用的,因为使用多个字段是不支持)
即:

IN 是把外表和内表做hash连接,而exists是对外表做loop循环,每次loop循环再对内表进行查询

如果查询的两个表大小相当,那么用in和exists差别不大。

如果两个表一个较小,一个较大,则子查询表大的用exists,子查询表小的用in

not in 和not exists:

如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;

而not exists 的子查询依然能用到表上的索引,所以无论那个表大,用not exists都比not in要快


© 2012 - 2023 记忆角落 网站统计
Theme by Wing
粤ICP备14056850号-1 又拍云CDN赞助