IN
確定給定的值是否與子查詢或列表中的值相匹配。
EXISTS
指定一個子查詢,檢測行的存在。
比較使用
EXISTS 和 IN 的查詢
這個例子比較了兩個語義類似的查詢。
第一個查詢使用 EXISTS 而第二個查詢使用 IN。注意兩個查詢返回相同的信息。
SELECT DISTINCT pub_name
FROM publishers
WHERE
EXISTS
(SELECT *
FROM titles
WHERE pub_id = publishers.pub_id
AND type = 'business')
-- Or, using the IN clause:
SELECT distinct pub_name
FROM publishers
WHERE pub_id
IN
(SELECT pub_id
FROM titles
WHERE type = 'business')
下面是任一查詢的結(jié)果集:
pub_name
----------------------------------------
Algodata Infosystems
New Moon Books
exits 相當(dāng)于存在量詞:表示集合存在,也就是集合不為空只作用一個集合.
例如 exist P表示P不空時(shí)為真; not exist P表示p為空時(shí)為真in表示一個標(biāo)量和一元關(guān)系的關(guān)系。
例如:s in P表示當(dāng)s與P中的某個值相等時(shí) 為真; s not in P 表示s與P中的每一個值都不相等時(shí) 為真
在Oracle SQL中取數(shù)據(jù)時(shí)有時(shí)要用到in 和
exists 那么他們有什么區(qū)別呢?
1)性能上的比較
比如Select * from T1 where x in ( select y from T2 )
執(zhí)行的過程相當(dāng)于:
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í)行的過程相當(dāng)于:
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é)果集很大需要消耗很多時(shí)間,但是T1比較小執(zhí)行( select null from t2 where y = x.x )非常快,那么
exists就比較適合用在這里
相對應(yīng)得子查詢的結(jié)果集比較小的時(shí)候就應(yīng)該使用in.
in和
exists
in 是把外表和內(nèi)表作hash 連接,而
exists是對外表作loop循環(huán),每次loop循環(huán)再對內(nèi)表進(jìn)行查詢。
一直以來認(rèn)為
exists比in效率高的說法是不準(zhǔn)確的。
如果查詢的兩個表大小相當(dāng),那么用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 那么內(nèi)外表都進(jìn)行全表掃描,沒有用到索引;
而not extsts 的子查詢依然能用到表上的索引。
所以無論那個表大,用not
exists都比not in要快。
in 與 =的區(qū)別
select name from student where name in ('zhang','wang','li','zhao');
與
select name from student where name='zhang' or name='li' or name='wang' or name='zhao'的結(jié)果是相同的。
posted on 2009-03-31 13:08
David1228 閱讀(4352)
評論(0) 編輯 收藏 所屬分類:
數(shù)據(jù)庫