in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。 
not exists:做NL,对子查询先查,有个虚表,有确定值,所以就算子查询有NULL最终也有值返回 
not in:做hash,对子查询表建立内存数组,用外表匹配,那子查询要是有NULL那外表没的匹配最终无值返回。 
    一直以来认为exists比in效率高的说法是不准确的。   
如果查询的两个表大小相当,那么用in和exists差别不大。  
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:   
例如:表A(小表),表B(大表) 1: 
select * from A where cc in (select cc from B)  效率低,用到了A表上cc列的索引; 
select * from A where exists(select cc from B where cc=A.cc)  效率高,用到了B表上cc列的索引。   
相反的 2: 
select * from B where cc in (select cc from A)  效率高,用到了B表上cc列的索引; 
select * from B where exists(select cc from A where cc=B.cc)  效率低,用到了A表上cc列的索引。   
not in 和not exists 
如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引; 而not extsts 的子查询依然能用到表上的索引。 所以无论那个表大,用not exists都比not in要快。 
一直听到的都是说尽量用exists不要用in,因为exists只判断存在而in需要对比值,所以exists比较快,但看了看网上的一些东西才发现根本不是这么回事。 下面这段是抄的 
Select * from T1 where x in ( select y from T2 ) 执行的过程相当于: select *  
  from t1, ( select distinct y from t2 ) t2  where t1.x = t2.y;  
select * from t1 where exists ( select null from t2 where y = x ) 执行的过程相当于:

for x in ( select * from t1 )    loop 
      if ( exists ( select null from t2 where y = x.x )       then  
         OUTPUT THE RECORD       end if end loop  
从我的角度来说,in的方式比较直观,exists则有些绕,而且in可以用于各种子查询,而exists好像只用于关联子查询(其他子查询当然也可以用,可惜没意义)。 
由于exists是用loop的方式,所以,循环的次数对于exists影响最大,所以,外表要记录数少,内表就无所谓了,而in用的是hash join,所以内表如果小,整个查询的范围都会很小,如果内表很大,外表如果也很大就很慢了,这时候exists才真正的会快过in的方式。    
not in 和not exists 
如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引; 而not extsts 的子查询依然能用到表上的索引。 所以无论那个表大,用not exists都比not in要快。 
 也就是说,in和exists需要具体情况具体分析,not in和not exists就不用分析了,尽量用not exists就好了。   
典型的连接类型共有3种:  
排序 - - 合并连接(Sort Merge Join (SMJ) )  嵌套循环(Nested Loops (NL) )  哈希连接(Hash Join)   
嵌套循环和哈希连接的算法还是有不同,在理论上哈希连接要快过排序和nl,当然实际情况比理论上有复杂的多,不过两者还是有差异的.   
1 关联子查询与非关联子查询 
 关联子查询需要在内部引用外部表,而非关联子查询不要引用外部表。对于父查询中处理的记录来说,一个关联子查询是每行计算一次,然而一个非关联子查询只会执行一次,而且结果集被保存在内存中(如果结果集比较小),或者放在一张oracle临时数据段中(如果结果集比较大)。一个“标量”子查询是一个非关联子查询,返回唯一记录。如果子查询仅仅返回一个记录,那么oracle优化器会将结果缩减为一个常量,而且这个子查询只会执行一次。 /*select * from emp where deptno in (select deptno from dept where dept_name='admin');*/ 2.如何选择?   根据外部查询,以及子查询本身所返回的记录的数目。如果两种查询返回的结果是相同的,哪一个效率更好? 
  关联子查询的系统开销:对于返回到外层查询的记录来说,子查询会每次执行一次。因此,必须保证任何可能的时候子查询都要使用索引。 
  非关联子查询的系统开销:子查询只会执行一次,而且结果集通常是排好序的,并保存在临时数据段中,其中每一个记录在返回时都会被父级查询引用,在子查询返回大量记录的情况下,将这些结果集排序回增大系统的开销。

所以:如果父查询只返回较少的记录,那么再次执行子查询的开销不会非常大,如果返回很多数据行,那么直查询就会执行很多次。 如果子查询返回较少的记录,那么为内存中保存父查询的结果集的系统开销不会非常大,如果子查询返回多行,那么需要将结果放在临时段上,然后对数据段排序,以便为负查询中的每个记录服务。   
3结论:1)在使用一个关联子查询是,使用in 或者 exists子句的子查询执行计划通常都相同 
       2)exists子句通常不适于子查询 
       3)在外部查询返回相对较少记录时,关联子查询比非关联子查询执行得要更快。        4)如果子查询中只有少量的记录,则非关联子查询会比关联子查询执行得更快。 4 子查询转化:子查询可以转化为标准连接操作        1)使用in的非关联子查询(子查询唯一) 
          条件:1)在整个层次结构中最底层数据表上定义唯一主键的数据列存在于子查询的select列表中 
                2)至少有个定义了唯一主键的数据列在select列表中,而且定义唯一主键的其他数据列都必须有指定的相等标准,不管是直接指定,还是间接指定。        2)使用exists子句的关联子查询 
          条件:对于相关条件来说,该子查询只能返回一个记录。   
5。not in和not exists调整 
  1)not in 非关联子查询:转化为in写法下的minus子句 
  2)not exists关联子查询:这种类型的反连接操作会为外部查询中每一个记录进行内部查询,除了不满足子查询中where条件的内部数据表以外,他会过滤掉所有记录。     可以重写:在一个等值连接中指定外部链接条件,然后添加select distinct     eg:select distinct ... from a,b where a.col1 = b.col1(+) and b.col1 is null 6。在子查询中使用all any

oracle中的exists和not exists和in用法详解的更多相关文章

  1. Android 中 View移动总结:ViewDragHelper学习及用法详解

    如上图简单呈现出两个方块后,提出一个需求: 1.拖动方块时,方块(即子View)可以跟随手指移动. 2.一个方块移动时,另一个方块可以跟随移动. 3.将方块移动到左边区域(右边区域)后放开(即手指离开 ...

  2. js中 call() 和 apply() 方法的区别和用法详解

    1.定义 每个函数都包含俩个非继承而来的方法:call() 和 apply()   call 和 apply 可以用来重新定义函数的的执行环境,也就是 this 的指向:call 和 apply 都是 ...

  3. sql: sybase与oracle中insert into select和select into的用法

    1. sybase与oracle中insert into select和select into的用法 http://wjlvivid.iteye.com/blog/1921679 Sybase 一.首 ...

  4. Oracle数据库中序列(SEQUENCE)的用法详解

    Oracle数据库中序列(SEQUENCE)的用法详解   在Oracle数据库中,序列的用途是生成表的主键值,可以在插入语句中引用,也可以通过查询检查当前值,或使序列增至下一个值.本文我们主要介绍了 ...

  5. mysql中event的用法详解

    一.基本概念mysql5.1版本开始引进event概念.event既“时间触发器”,与triggers的事件触发不同,event类似与linux crontab计划任务,用于时间触发.通过单独或调用存 ...

  6. Oracle 11g客户端在Linux系统上的配置步骤详解

    Oracle 11g客户端在Linux系统上的配置步骤详解 2011-07-26 10:47 newhappy2008 CSDN博客 字号:T | T 本文我们主要介绍了Oracle 11g客户端在L ...

  7. oracle正则表达式regexp_like的用法详解

    oracle正则表达式regexp_like的用法详解 /*ORACLE中的支持正则表达式的函数主要有下面四个:1,REGEXP_LIKE :与LIKE的功能相似2,REGEXP_INSTR :与IN ...

  8. oracle数据库定时任务dbms_job的用法详解

    本文来源:Ruthless <oracle数据库定时任务dbms_job的用法详解> 一.dbms_job涉及到的知识点   1.创建job: variable jobno number; ...

  9. oracle expdp/impdp 用法详解

    http://hi.baidu.com/hzfsai/item/4a4b3fc4b1cf7e51ad00efbd oracle expdp/impdp 用法详解 Data Pump 反映了整个导出/导 ...

  10. C#中string.format用法详解

    C#中string.format用法详解 本文实例总结了C#中string.format用法.分享给大家供大家参考.具体分析如下: String.Format 方法的几种定义: String.Form ...

随机推荐

  1. USACO Party Lamps

    题目大意:一排灯有n个,有4种开关,每种开关能改变一些灯现在的状态(亮的变暗,暗的变亮)现在已知一些灯的亮暗情况,问所以可能的情况是哪些 思路:同一种开关开两次显然是没效果的,那么枚举每个开关是否开就 ...

  2. uva 11235 RMQ范围最大值

    题目大意:给一个整数上升序列,对于一系列询问区间(i,j),回答这段区间出现次数最多值所出现的次数. 分析:一个上升序列,相同的值聚集在一起,把相同的值的区间看作一个整体,假设这样的整体有n个,把他们 ...

  3. 洛谷 P 1164 小A点菜

    题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:“随便点”. 题目描述 不过uim由于买了一些辅(e ...

  4. Redis数据结构之压缩列表

    压缩列表是Redis为了节约内存而开发的,由一系列特殊编码的连续内存块组成的顺序型数据结构.一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值. 一.压缩列表结构1. 压缩列 ...

  5. css3 nth-child 与 nth-of-type 的区别

    by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1709 一.深呼吸,直 ...

  6. CentOS7 docker.repo 用阿里云Docker Yum源

    yum安装软件的时候经常出现找不到镜像的情况 https://download.docker.com/linux/centos/7/x86_64/stable/repodata/repomd.xml: ...

  7. poj1159--Palindrome(dp:最长公共子序列变形 + 滚动数组)

    Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 53414   Accepted: 18449 Desc ...

  8. CSS3中transition-duration參数对hover前后两种过渡时间的影响

    transition-duration这个參数是设置过渡时间的,将transition-duration放在哪个类中.那么在这个类被启用时就会依照transition-duration设定的时间来过渡 ...

  9. UltraEdit UE常见问题 使用必读

    1 UE设置出多个tag标签,能切换的那种样子 现在的现象就是图上显示的样子,我想弄出来多个标签能切换的样子,就像浏览器的多个标签那样,怎么操作呢 视图->视图/列表->打开文件标签可以使 ...

  10. Android开发之入口Activity

    Android开发之入口Activity Adnroid App是怎样确定入口Activity的? 难道就由于class的类名叫MainActivity,布局文件叫activity_main.xml? ...