A表和B表,
A表有1百万条记录,B表有1千万条记录。
sql:select * from a where not exists(select * from b where b.code=a.code);当B表的code列上建有索引i_idx时,执行计划如下
.......
hash join anti
   table access full      a       ......
   index fast full scan   i_idx   .....当B表的code列上无索引时,执行计划如下
.......
hash join anti
   table access full      a       ......
   table access full      b       .....
我对exists的理解:
对外表a的每条记录进行扫描,每扫描一条记录后,就执行一次对内表B的查询(即:select * from b where b.code=a.code),
这样就类似一个循环,每循环1下,就执行1下对内表B的查询(即:select * from b where b.code=a.code),
这样的话表连接应是嵌套循环连接。问题:
1、我的理解对吗?
2、为什么执行计划里是hash join?而不是nested loops?
3、当我把not exists 改为exists 时,就看到hash join semi,请问anti与semi的区别 ?

解决方案 »

  1.   

    in和exists对数据的处理方法:假如使用IN,执行过程将如同下列所示:
      
      Select * from T1 where x in ( select y from T2 )
      
      LIKE:
      
      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 )
      
      LIKE:
      
      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
      

  2.   

    http://www.itpub.net/viewthread.php?tid=835911
    可以看看HASH JOIN原理
      

  3.   

    1.  基本上是这样的,基于CBO的优化,对于exists类的查询,默认外表为驱动表。
    2. 一般来说对于返连接的表比较小,返回的数据集比如说少于1万,那么采用nest loop可能性能较好,相反,有成百上千万的记录,hash join效率较高。
    3. hash join semi是针对类似exists的,如果在内层扫描中,命中就立即返回本轮匹配,而hash join anti则相反。
      

  4.   

    select * from a where not exists(select * from b where b.code=a.code and rownum =1)加个rownum, 执行计划就不一样了,执行速度也就不一样了
      

  5.   

    你这样把逻辑也改了·再好的SQL有人敢用吗?
      

  6.   

    老兵哥,既然认为我的理解是对的,那就是个循环,也就是nested loop,怎么还会有hash join??
    难道哈希连接也是个循环,每循环一次,
    就执行1下对内表B的查询(即:select * from b where b.code=a.code)??
      

  7.   

    我理解的exists也是相当于两层for循环。
      

  8.   

    我觉得加rownum=1没错啊,为啥逻辑边了???没看出来!
      

  9.   

    散列连接是CBO 做大数据集连接时的常用方式,优化器使用两个表中较小的表(或数据
    源)利用连接键在内存中建立散列表,然后扫描较大的表并探测散列表,找出与散列表匹配
    的行