Posted on 2006-04-18 16:01
Terry的Blog 閱讀(23029)
評論(5) 編輯 收藏 所屬分類:
oracle
在Oracle SQL中取數(shù)據(jù)時有時要用到in 和 exists 那么他們有什么區(qū)別呢?
1 性能上的比較
比如Select * from T1 where x in ( select y from T2 )
執(zhí)行的過程相當于:
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 )
執(zhí)行的過程相當于:
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
表?T1 不可避免的要被完全掃描一遍
分別適用在什么情況?
以子查詢?( select y from T2 )為考慮方向
如果子查詢的結(jié)果集很大需要消耗很多時間,但是T1比較小執(zhí)行( select null from t2 where y = x.x )非常快,那么exists就比較適合用在這里
相對應(yīng)得子查詢的結(jié)果集比較小的時候就應(yīng)該使用in.
2 含義上的比較
在標準的scott/tiger用戶下
???
|
EMPNO
|
ENAME
|
JOB
|
MGR
|
HIREDATE
|
SAL
|
COMM
|
DEPTNO
|
1
|
7499
|
ALLEN
|
SALESMAN
|
7698
|
1981/02/20
|
1600.00
|
300.00
|
30
|
2
|
7521
|
WARD
|
SALESMAN
|
7698
|
1981/02/22
|
1250.00
|
500.00
|
30
|
3
|
7566
|
JONES
|
MANAGER
|
7839
|
1981/04/02
|
2975.00
|
|
20
|
4
|
7654
|
MARTIN
|
SALESMAN
|
7698
|
1981/09/28
|
1250.00
|
1400.00
|
30
|
5
|
7698
|
BLAKE
|
MANAGER
|
7839
|
1981/05/01
|
2850.00
|
|
30
|
6
|
7782
|
CLARK
|
MANAGER
|
7839
|
1981/06/09
|
2450.00
|
|
10
|
7
|
7788
|
SCOTT
|
ANALYST
|
7566
|
1987/04/19
|
3000.00
|
|
20
|
8
|
7839
|
KING
|
PRESIDENT
|
|
1981/11/17
|
5000.00
|
|
10
|
9
|
7844
|
TURNER
|
SALESMAN
|
7698
|
1981/09/08
|
1500.00
|
0.00
|
30
|
10
|
7876
|
ADAMS
|
CLERK
|
7788
|
1987/05/23
|
1100.00
|
|
20
|
11
|
7900
|
JAMES
|
CLERK
|
7698
|
1981/12/03
|
950.00
|
|
30
|
12
|
7902
|
FORD
|
ANALYST
|
7566
|
1981/12/03
|
3000.00
|
|
20
|
13
|
7934
|
MILLER
|
CLERK
|
7782
|
1982/01/23
|
1300.00
|
|
10
|
執(zhí)行
SQL> select count(*) from emp where empno not in ( select mgr from emp );
COUNT(*)
----------
???????? 0
SQL> select count(*) from emp T1
? 2? where not exists ( select null from emp T2 where t2.mgr = t1.empno ); -- 這里子查詢中取出null并沒有什么特殊作用,只是表示取什么都一樣。
COUNT(*)
----------
???????? 8
結(jié)果明顯不同,問題就出在MGR=null的那條數(shù)據(jù)上。任何值X not in (null)? 結(jié)果都不成立。
用一個小例子試驗一下:
select * from dual where dummy not in ( NULL ) -- no rows selected
select * from dual where NOT( dummy not in ( NULL ) ) --no rows selected
知覺上這兩句SQL總有一句會取出數(shù)據(jù)的,但是實際上都沒有。SQL中邏輯表達式的值可以有三種結(jié)果(true false null)而null相當于false.