1 IN和EXISTS关键字是不是都是对记录集合的检测?  比如 SELECT 记录 FORM 记录集1 WHERE NO EXISTS ( SELECT 记录 FORM 记录集1 WHERE 记录集1.ID=记录集2.ID)2 IN和EXITS关键字有什么区别?

解决方案 »

  1.   

    not   exists       --这个结果集中是否存在,只要有一条纪录他就为     "TRUE " 
    not   in       ---是指在这个结果集中是否存在,是否和这个结果集中的值对应
      

  2.   

    in/not in和exist/not exists我觉得主要在于性能上的区别:
    本质是因为使用in 或not in时,基于rule的优化器趋向于使用nested loop方式关联,而使用exists 或not exists时,系统趋向于使用hash join方式关联。但如果是基于COST的优化器时,且统计信息比较准确,则ORACLE会自动转换其执行计划,跟使用in或exists关系不大。
      

  3.   

    exists返回的是真假值,只要找到一条true的就会返回,不会继续查找下去,所以会导致效率上的差异
    除此之外,使用上也会有点小差异,从而导致结果上也有不同,比如:14:20:46 SQL> create table t1(a int);
    表已创建。
    已用时间:  00: 00: 00.00
    14:20:53 SQL> create table t2(a int);
    表已创建。
    已用时间:  00: 00: 00.00
    14:20:53 SQL>
    14:20:53 SQL> insert into t1 values (1);
    已创建 1 行。
    已用时间:  00: 00: 00.00
    14:20:53 SQL> insert into t1 values (null);
    已创建 1 行。
    已用时间:  00: 00: 00.00
    14:20:53 SQL> insert into t1 values (2);
    已创建 1 行。
    已用时间:  00: 00: 00.00
    14:20:53 SQL>
    14:20:53 SQL> insert into t2 values (1);
    已创建 1 行。
    已用时间:  00: 00: 00.00
    14:21:09 SQL> select rownum,a from t1 where a not in (select a from t2);
        ROWNUM          A
    ---------- ----------
             1          2
    已用时间:  00: 00: 00.00
    14:21:26 SQL> select rownum,a from t1 where not exists (select 1 from t2 where t
    2.a=t1.a);
        ROWNUM          A
    ---------- ----------
             1
             2          2
    已用时间:  00: 00: 00.00
      

  4.   

    in中的子查询会做排序
    IN的执行流程   select * from T1 where x in ( select y from T2 )   
    可以理解为:   select * from t1, ( select distinct y from t2 ) t2 where t1.x = t2.y;EXISTS的执行流程 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较快。
    分析表后无论用IN还是EXISTS都变得更快,由于执行计划一样,所以速度一样;NOT EXISTS的执行流程  select .....    from rollup R  where not exists ( select 'Found' from title T                                where R.source_id = T.Title_ID);  可以理解为:  for x in ( select * from rollup )         loop            if ( not exists ( that query ) ) then                   OUTPUT            end if;         end;NOT EXISTS 与 NOT IN 不能完全互相替换,看具体的需求。如果选择的列可以为空,则不能被替换。
    对于not in 和 not exists的性能区别
    not in 只有当子查询中,select 关键字后的字段有not null约束或者有这种暗示时用not in
    如果主查询中表大,子查询中的表小但是记录多,则应当使用not in,并使用anti hash join. 用表连接替换EXISTS
    通常来说 , 采用表连接的方式比EXISTS更有效率
    SELECT ENAME FROM EMP E WHERE EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT_NO = E.DEPT_NO AND DEPT_CAT = ‘A’);
    更高效
    SELECT ENAME FROM DEPT D,EMP E WHERE E.DEPT_NO = D.DEPT_NO AND DEPT_CAT = ‘A’ ;