从效率来看:

1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ;

T1数据量小而T2数据量非常大时,T1<<T2 时,1) 的查询效率高。

2) select * from T1 where T1.a in (select T2.a from T2) ;

T1数据量非常大而T2数据量小时,T1>>T2 时,2) 的查询效率高。

简而言之,一般式:外表大,用IN;内表大,用EXISTS。

执行方式:

通过使用EXISTS,Oracle会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间。Oracle在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在一个加了索引的临时表中。在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。这也就是使用EXISTS比使用IN通常查询速度快的原因。

  1. in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询
  2. not exists:做NL,对子查询先查,有个虚表,有确定值,所以就算子查询有NULL最终也有值返回
  3. 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

原文地址http://muyue123.blog.sohu.com/146930118.html

IN和EXISTS、not in 和not exists的效率详解的更多相关文章

  1. SQL里的EXISTS与in、not exists与not in

    系统要求进行SQL优化,对效率比较低的SQL进行优化,使其运行效率更高,其中要求对SQL中的部分in/not in修改为exists/not exists 修改方法如下: in的SQL语句 SELEC ...

  2. oracle中的exists 和 in 用法详解

    以前一直不知道exists和in的用法与效率,这次的项目中需要用到,所以自己研究了一下.下面是我举两个例子说明两者之间的效率问题. 前言概述: “exists”和“in”的效率问题,涉及到效率问题也就 ...

  3. IN和EXISTS的详解

    从效率来看: 1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ; T1数据量小而T2数据量非常大时,T1<& ...

  4. oracle中的exists 和not exists 用法详解

    有两个简单例子,以说明 “exists”和“in”的效率问题 1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ; ...

  5. oracle中的exists 和not exists 用法详解(转)

    有两个简单例子,以说明 “exists”和“in”的效率问题 1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ; ...

  6. 【转载】[ORACLE]详解not in与not exists的区别与用法

    在网上搜了下关于oracle中not exists和not in性能的比较,发现没有描述的太全面的,可能是问题太简单了,达人们都不屑于解释吧.于是自己花了点时间,试图把这个问题简单描述清楚,其实归根结 ...

  7. EXISTS的使用详解

    .exists的使用场合: exists 用于只能用于子查询,可以替代in,若匹配到结果,则退出内部 查询,并将条件标志为true,传回全部结果资料,in 不管匹配到匹配不到都 全部匹配完毕,使用ex ...

  8. 转://Oracle not in查不到应有的结果(NULL、IN、EXISTS详解)

    问题: 语句1 : Select   *   from   table1 A  where  A.col1  not   in  (  select  col1  from  table2 B )  ...

  9. Oracle exists 和not exists 用法详解

    有两个简单例子,以说明 “exists”和“in”的效率问题 1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ; ...

随机推荐

  1. finally代码块的执行

    try{ //todo }catch(Exception e){ //todo }finally{ //todo } 1.不管try,catch里面的代码快有无return,finally都会执行 2 ...

  2. Java内存管理-探索Java中字符串String(十二)

    做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 一.初识String类 首先JDK API的介绍: public final class String extends O ...

  3. 梯度直方图(HOG,Histogram of Gradient)

    1.介绍 HOG(Histogram of Oriented Gradient)是2005年CVPR会议上,法国国家计算机科学及自动控制研究所的Dalal等人提出的一种解决人体目标检测的图像描述子,该 ...

  4. 关于SpringBoot的自动配置和启动过程

    一.简介 Spring Boot简化了Spring应用的开发,采用约定大于配置的思想,去繁从简,很方便就能构建一个独立的.产品级别的应用. 1.传统J2EE开发的缺点 开发笨重.配置繁多复杂.开发效率 ...

  5. LeetCode:1179.重新格式化部门表

    题目链接:https://leetcode-cn.com/problems/reformat-department-table/ 题目 部门表 Department: +--------------- ...

  6. css流程图

     图片链接:https://mp.processon.com/view/link/5da65435e4b0ea86c2b1fb05 之前是图片链接是有点问题,不知道什么原因被删除了,现在已经更新了,如 ...

  7. 基于create-react-app脚手架,按需加载antd组件以及less样式

    摘要 为了更好的书写css样式,在react中引入less,在网上查询了许多关于react引入less样式文件的资料,大多数都是需要在react项目中npm run eject暴露出底层文件,然后在底 ...

  8. vue中非父子组件的传值bus的使用

    非父子之间的组件传值,可以使用vuex.简单的状态管理,也可以用vue bus vue bus可以实现不同组件间.不同页面间的通信,比如我在A页面出发点击事件,要B页面发生变化,使用方法如下: 全局定 ...

  9. JavaScript 的查询机制——LHS 与 RHS

    JavaScript 引擎在查找一个变量的时候,有两种查找机制:LHS 和 RHS. RHS 的查询是简单地查找到某个变量的值,而 LHS 则是试图找到变量的容器的本身. 一个简单的例子:当我们执行 ...

  10. python3学习特性

    一 实例变量与类变量 class Pepple: __age=18 __name="zhangfff" @classmethod def GetInfo(cls): print(c ...