`
ruyi574812039
  • 浏览: 43693 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

oracle 中not in 与 not exists 执行效率到底谁高谁低?

阅读更多
网上相关信息很多很多,到底not in 与  not  exists谁的效率高,说实话,我也不知道!
select  count(1)  from ba_ry_jbxx a  where  not  exists   (select b.gmsfzh from ba_ry_zgkssh  b  where    a.gmsfzh = b.gmsfzh);
select  count(1)  from ba_ry_jbxx a  where  a.gmsfzh not  in    (select b.gmsfzh from ba_ry_zgkssh  b );
以下针对这两条语句分析:

说到比较,首先得有共同点才会去比较,共同点就是:都可以查询a表中的gmsfzh字段的值不在b表中的gmsfzh字段里的记录数。
前提条件是首先得保证这两个语句查询的数据的正确性,才可以进行效率的比较。
(1)当b表中的gmsfzh字段有空值时,用not in查询结果为0.所以这两个语句比较效率就没有任何意义了!就直接用not exists!
(2)当a表中的gmsfzh字段有空值时,查询结果固然也不一样,用 not  exists 查询的记录数会大于用not  in的记录数,因为 not  exists把空值也
作为查询结果了,而not  in不把空值作为结果。
(
至于为什么,我的理解是:因为not  exists会关联a.gmsfzh = b.gmsfzh一下,除了关联上的数据其他的在a表中剩下的记录都认为不在b表中,因为空值肯定是关联不上的,
所以就认为空值不在b表中。
而为什么用not in时,a表中的空值就不算在查询结果内呢!因为oracle就这么规定的)

所以当a表中的gmsfzh字段有空值时,因为查询结果都不一样,你觉得哪个查询结果是正确的,固然就用哪个!

如果排除两个表的空值的问题,或者说a表中的空值并不影响查询结果的正确性时,接下来可以考虑not in 和not  exists的执行效率问题了:

数据量情况:a表 100条记录, b表 70000条记录,执行以下两语句:
select  count(1)  from ba_ry_jbxx a  where  not  exists   (select b.gmsfzh from ba_ry_zgkssh  b  where    a.gmsfzh = b.gmsfzh);
select  count(1)  from ba_ry_jbxx a  where  a.gmsfzh not  in    (select b.gmsfzh from ba_ry_zgkssh  b );
当两个表都为gmsfzh字段建了索引的情况下
实测结果如下:
用not  exists,耗时0.015秒。
用not  in,耗时50.641秒。
这差距还真有点大。。。
毫无疑问,用not  exists走索引了,而not  in 并不走索引。

当删除两个表的索引之后:
实测结果如下:
用not  exists,耗时50秒。
用not  in,耗时 50.875秒,此时not  exists和not in 几乎差不多。

数据量不变,反过来测试:
select  count(1)  from ba_ry_zgkssh b  where  not  exists   (select a.gmsfzh from ba_ry_jbxx  a  where    b.gmsfzh = a.gmsfzh);
select  count(1)  from ba_ry_zgkssh b  where  b.gmsfzh not  in    (select a.gmsfzh from ba_ry_jbxx  a );
无索引:
用not  in,耗时 3.703秒.
用not  exists,耗时3.641秒。(此时至少说明,无索引的情况下,b表数据量远远大于a表时,not in与not exists效率差不多)

建完索引后:
用not  in,耗时 3.937秒.
用not  exists,耗时0.813秒。

以上数据测试可见,索引的重要性。


我总觉得,not in既然存在,肯定有他存在的道理。
测试这么多,至少证明,有索引的情况下,多数时候not exists完虐not  in的执行效率。
现在我纠结的问题就是,到底什么情况下not  in效率要高于not exists? 还请高人留言指点一下。
分享到:
评论

相关推荐

    Oracle数据库Sql性能调优

    1.20 用NOT EXISTS替代NOT IN 12 1.21 用表连接替换EXISTS 13 1.22 用EXISTS替换DISTINCT 13 1.23 识别’低效执行’的SQL语句 14 1.24 用索引提高效率 14 1.25 索引的操作 15 1.26 多个平等的索引 16 1.27 等式比较...

    oracle sql performance tuning

    3.1 绝大多数情况下NOT EXISTS比NOT IN 效率高 6 3.2 UNION ALL效率比UNION高很多 6 3.3 一些很耗资源的SQL操作,在不必要的情况下不要使用 6 3.4 通常联接查询比子查询的效率要高很多 7 3.5 用TABLE 索引(INDEX)...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    从就业与择业的角度来讲,计算机相关专业的大学生从事oracle方面的技术是职业发展中的最佳选择。 其一、就业面广:全球前100强企业99家都在使用ORACLE相关技术,中国政府机构,大中型企事业单位都能有ORACLE技术的...

    oracle数据库sql的优化总结

    一:使用where少使用having; 二:查两张以上表时,把记录少的放在右边;...十一:not exists代替 not in(not in 字句将执行一个内部的排序和合并,任何情况下,not in是最低效的,子查询中全表扫描了。为了避免使用n

    Oracle事例

    20.oracle8中扩充了group by rollup和cube的操作。有时候省了你好多功夫的。 下面的语句可以进行总计 select region_code,count(*) from aicbs.acc_woff_notify group by rollup(region_code); <2> 对第1个字段...

    SQL性能优化

     在FROM后面的表中的列表顺序会对SQL执行性能影响,在没有索引及ORACLE没有对表进行统计分析的情况下ORACLE会按表出现的顺序进行链接,由此因为表的顺序不对会产生十分耗服务器资源的数据交叉。(注:如果对表进行...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    本书是第II卷,以开发人员在项目开发中经常遇到的问题和必须掌握的技术为中心,介绍了应用Java进行桌面程序开发各个方面的知识和技巧,主要包括Java语法与面向对象技术、Java高级应用、窗体与控件应用、文件操作...

    SQL语法大全

    sql="select * from 数据表 where 字段名 in (\'值1\',\'值2\',\'值3\')" sql="select * from 数据表 where 字段名 between 值1 and 值2" (2) 更新数据记录: sql="update 数据表 set 字段名=字段值 where 条件...

Global site tag (gtag.js) - Google Analytics