in和exists

  in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。一直以来认为exists比in效率高的说法是不准确的。

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

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

  例如:表A(小表),表B(大表)

    效率低,用到了A表上cc列的索引:select * from A where cc in (select cc from B)

    效率高,用到了B表上cc列的索引:select * from A where exists(select cc from B where cc=A.cc)

  相反的:

    效率高,用到了B表上cc列的索引:select * from B where cc in (select cc from A)

    效率低,用到了A表上cc列的索引:select * from B where exists(select cc from A where cc=B.cc)

not in 和not exists

  如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。

  not in 逻辑上不完全等同于not exists,如果你误用了not in,小心你的程序存在致命的BUG:

  请看下面的例子:

  create table t1 (c1 number,c2 number);

  create table t2 (c1 number,c2 number);

  insert into t1 values (1,2);

  insert into t1 values (1,3);

  insert into t2 values (1,2);

  insert into t2 values (1,null);

  select * from t1 where c2 not in (select c2 from t2);

  --no rows found

  select * from t1 where not exists (select 1 from t2 where t1.c2=t2.c2);

  --c1 c2

  --1 3

正如所看到的,not in 出现了不期望的结果集,存在逻辑错误。如果看一下上述两个select语句的执行计划,也会不同。后者使用了hash_aj。

因此,请尽量不要使用not in(它会调用子查询),而尽量使用not exists(它会调用关联子查询)。如果子查询中返回的任意一条记录含有空值,则查询将不返回任何记录,正如上面例子所示。

除非子查询字段有非空限制,这时可以使用not in ,并且也可以通过提示让它使用hasg_aj或merge_aj连接

在程序中,我们经常会习惯性的使用in和not in,在访问量比较小的时候是可以的,但是一旦数据量大了,我们就推荐使用not exists或者外连接来代替了。
如果要实现一张表有而另外一张表没有的数据时,我们通常会这么写:

select * from table t where t.id not in (select id from table2)

我们可以使用下面的语句代替:

select a.* from table1 a left join table2 b on a.id = b.id where b.id is null; 
select a.* from table1 a left join table2 b on a.id = b.id where b.id is not null; 

in 与 exist , not in 与 not exist的更多相关文章

  1. Error resolving template [xxx], template might not exist or might not be exist

    Springboot+thymeleaf+mybatis 抛Error resolving template [xxx], template might not exist的异常 原因是我们在pom. ...

  2. in与exist , not in与not exist 的区别(转)

    in和exists  in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询.一直以来认为exists比in效率高的说法是不准确的.  如果查询的 ...

  3. in与exist , not in与not exist 的区别

    in和exists     in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询.一直以来认为exists比in效率高的说法是不准确的.     ...

  4. DOS/BAT批处理if exist else 语句的几种用法

    在DOS批处理命令中常常会通过if语句来进行判断来执行下面的命令, 那么批处理if语句怎么用呢,下面学无忧小编就来说说有关批处理if以及if exist else语句的相关内容.一.批处理if书写格式 ...

  5. Android之Dedug--Circular dependencies cannot exist in AnimatorSet

    今日,在学习AnimatorSet时,使用play.with.after.before时,代码书写如下: ObjectAnimator animator1 = ObjectAnimator.ofFlo ...

  6. No-args constructor for class X does not exist. Register an InstanceCreator with Gson for this type to fix this problem.

    Gson解析JSON字符串时出现了下面的错误: No-args constructor for class X does not exist. Register an InstanceCreator ...

  7. MySQL: Table 'mysql.plugin' doesn't exist的解决

    安装解压版MySQL以后,不能启动,日志里面出现了这个错误: MySQL: Table 'mysql.plugin' doesn't exist 这是因为mysql服务启动时候找不到内置数据库&quo ...

  8. 解决 release-stripped.ap_' specified for property 'resourceFile' does not exist.

    设置buildTypes里的release的shrinkResources为false即可,如果是 release-stripped.ap_' specified for property 'reso ...

  9. Mac 下locate命令使用问题WARNING: The locate database (/var/db/locate.database) does not exist.

    想在Mac下使用locate时,提醒数据库没创建: WARNING: The locate database (/var/db/locate.database) does not exist. To ...

随机推荐

  1. 【转】上拉下拉电阻、I/O输出(开漏、推挽等)

    作者:BakerZhang 链接:https://www.jianshu.com/p/3ac3a29b0f58来源:简书 感谢! ——————————————————————————————————— ...

  2. 启动模拟器的qq

    #coding = utf-8from appium import webdriver '''1.手机类型2.版本3.手机的唯一标识 deviceName4.app 包名appPackage5.app ...

  3. 【剑指Offer】30、连续子数组的最大和

      题目描述:   HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是 ...

  4. 继续聊WPF——自定义CheckBox控件外观

    上一篇文章中谈到了BulletDecorator控件,就是为自定义CheckBox控件的模板做准备,因为CheckBox需要比较严格的布局,正好,BulletDecorator控件就合适了,该控件的布 ...

  5. java的几种对象(PO,VO,DAO,BO,POJO)解释 (转)

    java的几种对象(PO,VO,DAO,BO,POJO)解释 一.PO:persistant object 持久对象,可以看成是与数据库中的表相映射的java对象.最简单的PO就是对应数据库中某个表中 ...

  6. LightOJ - 1189 - Sum of Factorials

    先上题目 Sum of Factorials Time Limit:500MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu ...

  7. Elasticsearch 分页坑之---评分一致导致数错乱

    面试:你懂什么是分布式系统吗?Redis分布式锁都不会?>>>   1.背景介绍 最近搞es搜索,match查询默认按照评分排序,发现有一部分数据评分一致,一开始也没注意,客户端调用 ...

  8. 日志输出最不重要的就是控制台输出,控制台输出就是system.out而已

    1.日志输出最不重要的就是控制台输出,控制台输出就是system.out而已 2.所以日志输出时候会存在一个Bug就是:stdout要配置在日志输出的最前面,因为stdout控制台输出,最不重要,如果 ...

  9. 怎样 获取 ios的系统版本

    获得Ios系统版本的函数,比方 函数定义: [cpp] view plaincopy + (float)getIOSVersion; 函数实现: [cpp] view plaincopy + (flo ...

  10. 8 Reasons why SharePoint is Bad for Your Business 8个理由告诉你,为什么SharePoint对你的业务有害

    8 Reasons why SharePoint is Bad for Your Business 8个理由告诉你,为什么SharePoint对你的业务有害         SharePoint近期已 ...