in 和 Exists的用法區別

in 和 Exists的用法區別
2007-03-19 14:30
1.
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
對於inexists的性能區別:
   
如果子查詢得出的結果集記錄較少,主查詢中的表較大且又有索引時應該用in,反之如果外層的主查詢記錄較少,子查詢中的表大,又有索引時使用exists
   
其實我們區分inexists主要是造成了驅動順序的改變(這是性能變化的關鍵),如果是exists,那麼以外層表爲驅動表,先被訪問,如果是IN,那麼先執行子查詢,所以我們會以驅動表的快速返回爲目標,那麼就會考慮到索引及結果集的關係了
                            
另外IN時不對NULL進行處理
如:
select 1 from dual where null  
in (0,1,2,null)
2.NOT INNOT 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不能完全互相替換,看具體的需求。如果選擇的列可以爲空,則不能被替換。

例如下面語句,看他們的區別:
select x,y from t;
x               y
------          ------
1               3
3         1
1         2
1         1
3         1
5
select * from t where   x not
in (select y from t t2   )
no rows
        
select * from t where   not
exists (select null from t t2
                                                   where t2.y=t.x )
x        y
------   ------
5        NULL
所以要具體需求來決定

對於not in not exists的性能區別:
    not
in只有當子查詢中,select 關鍵字後的字段有not null約束或者有這種暗示時用not in,另外如果主查詢中表大,子查詢中的表小但是記錄多,則應當使用not in,並使用anti hash join.
   
如果主查詢表中記錄少,子查詢表中記錄多,並有索引,可以使用not exists,另外not in最好也可以用/*+ HASH_AJ */或者外連接+is null
NOT
IN在基於成本的應用中較好

比如:
select .....
from rollup R
where not
exists ( select 'Found' from title T
                            where R.source_id = T.Title_ID);

改成(佳)

select ......
from title T, rollup R
where R.source_id = T.Title_id(+)
     and T.Title_id is null;
                                  
或者(佳)
sql> select /*+ HASH_AJ */ ...
         from rollup R
         where ource_id NOT
IN ( select ource_id
                                                from title T
                                               where ource_id IS NOT NULL )
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章