Oracle in與exist條件分析

2021-05-23 07:48:58 字數 2176 閱讀 2504

在撰寫sql時,常常會煩惱要使用in or 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

所以能想想其中差異,當子查詢的**是個儲存巨大資料量的**時,則使用第乙個方法的效能將比較差,因為他的執行計畫是使用sort merge join,相對的如果子查詢的table相對比較小,使用in的執行效率應該比較佳。

而如果外部的**(例如t1)是相對的儲存大量資料,則?用第乙個方法in的效率將會比較好,如果你使用exists,則除了會對t1這個bigtable進行full scan外,還會一筆一筆讀取所有t1的資料列,效能自然較差。簡單的一句話,外大內小=in,外小內大=exists,這是個實用的概略評估方法,在大部分的情況下是適用的。

有兩個簡單例子,以說明 「exists」和「in」的效率問題

1) select * from t1 where exists(select 1 from t2 where t1.a=t2.a) ;

t1資料量小而t2資料量非常大時,t1<>t2 時,2) 的查詢效率高。

exists 用法:

請注意 1)句中的有顏色字型的部分 ,理解其含義;

其中 「select 1 from t2 where t1.a=t2.a」 相當於乙個關聯表查詢,相當於

「select 1 from t1,t2 where t1.a=t2.a」

但是,如果你噹噹執行 1) 句括號裡的語句,是會報語法錯誤的,這也是使用exists需要注意的地方。

「exists(***)」就表示括號裡的語句能不能查出記錄,它要查的記錄是否存在。

因此「select 1」這裡的 「1」其實是無關緊要的,換成「*」也沒問題,它只在乎括號裡的資料能不能查詢出來,是否存在這樣的記錄,如果存在,這 1) 句的where 條件成立。

in 的用法:

繼續引用上面的例子

「2) select * from t1 where t1.a in (select t2.a from t2) 」

這裡的「in」後面括號裡的語句搜尋出來的字段的內容一定要相對應,一般來說,t1和t2這兩個表的a欄位表達的意義應該是一樣的,否則這樣查沒什麼意義。

打個比方:t1,t2表都有乙個字段,表示工單號,但是t1表示工單號的欄位名叫「ticketid」,t2則為「id」,但是其表達的意義是一樣的,而且資料格式也是一樣的。這時,用 2)的寫法就可以這樣:

「select * from t1 where t1.ticketid in (select t2.id from t2) 」

select name from employee where name not in (select name from student);

select name from employee where not exists (select name from student);

第一句sql語句的執行效率不如第二句。

通過使用exists,oracle會首先檢查主查詢,然後執行子查詢直到它找到第乙個匹配項,這就節省了時間。oracle在執行in子查詢時,首先執行子查詢,並將獲得的結果列表存放在乙個加了索引的臨時表中。在執行子查詢之前,系統先將主查詢掛起,待子查詢執行完畢,存放在臨時表中以後再執行主查詢。這也就是使用exists比使用in通常查詢速度快的原因。

in(...)裡面的列表 "資料量大 "的話,恐怕樓主得注意限制喲:)

9i的限制是1000~~~~不然會出錯的

In與Exist的區別

in 遍歷 exists 檢索到滿足條件即退出 not exists 檢索到不滿足條件即退出 本質區別 exists 由於exist屬於外驅動,故會利用索引來檢索資料 in 則屬於內驅動 故不能利用索引檢索資料 其中,in和not in類似全表掃瞄,效率低,一般用 exist和notexist代替其...

Exist 與in 的區別

exist是乙個存在判斷,in是乙個集合運算子,a in 這個運算中,前面是乙個元素,後面是乙個集合,集合中的元素型別是和前面的元素一樣的.而exists是乙個存在判斷,如果後面的查詢中有結果,則exists為真,否則為假.in 運算用在語句中,它後面帶的select 一定是選乙個字段,而不是sel...

exist與in的區別

對於in 和 exists的效能區別 如果子查詢得出的結果集記錄較少,主查詢中的表較大且又有索引時應該用in,反之如果外層的主查詢記錄較少,子查詢中的表大,又有索引時使用exists。其實我們區分in和exists主要是造成了驅動順序的改變 這是效能變化的關鍵 如果是exists,那麼以外層表為驅動...