ORACLE in與exists語句的區別

2021-06-27 22:52:14 字數 3309 閱讀 4243

一、例項:

insert into his_batch_excel_data

select 3402 as batch_id,

t.excel_name,

t.op_time,

t.staff_id,

2 state,

t.imp_type,

t.acc_nbr,

t.mkt_comm_code,

t.no_state,

'合同號不存在' mark

from batch_excel_data t

where t.batch_id = 3401

and t.imp_type = 1

andnot exists (select acct_code

from odsstat.mid_acct_day partition(p20141229)

where acct_code = t.acc_nbr)

and t.state = 0

二、例子:

1.例一:

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

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

t1資料量小而t2資料量非常大時,t1<2) select * from t1 where t1.a in (select t2.a from t2) ;

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通常查詢速度快的原因

2.例二:

select * from a

where id in(select id from b)

以上查詢使用了in語句,in()只執行一次,它查出b表中的所有id欄位並快取起來.之後,檢查a表的id是否與b表中的id相等,如果相等則將a表的記錄加入結果集中,直到遍歷完a表的所有記錄.

它的查詢過程類似於以下過程

list resultset=;

array a=(select * from a);

array b=(select id from b);

for(int i=0;i

for(int j=0;j

if(a[i].id==b[j].id) }}

return resultset;

可以看出,當b表資料較大時不適合使用in(),因為它會b表資料全部遍歷一次.

如:a表有10000條記錄,b表有1000000條記錄,那麼最多有可能遍歷10000*1000000次,效率很差.

再如:a表有10000條記錄,b表有100條記錄,那麼最多有可能遍歷10000*100次,遍歷次數大大減少,效率大大提公升.

結論:in()適合b錶比a表資料小的情況

select a.* from a a

where exists(select 1 from b b where a.id=b.id)

以上查詢使用了exists語句,exists()會執行a.length次,它並不快取exists()結果集,因為exists()結果集的內容並不重要,重要的是結果集中是否有記錄,如果有則返回true,沒有則返回false.

它的查詢過程類似於以下過程

list resultset=;

array a=(select * from a)

for(int i=0;i

if(exists(a[i].id)

}return resultset;

當b錶比a表資料大時適合使用exists(),因為它沒有那麼遍歷操作,只需要再執行一次查詢就行.

如:a表有10000條記錄,b表有1000000條記錄,那麼exists()會執行10000次去判斷a表中的id是否與b表中的id相等.

如:a表有10000條記錄,b表有100000000條記錄,那麼exists()還是執行10000次,因為它只執行a.length次,可見b表資料越多,越適合exists()發揮效果.

再如:a表有10000條記錄,b表有100條記錄,那麼exists()還是執行10000次,還不如使用in()遍歷10000*100次,因為in()是在記憶體裡遍歷比較,而exists()需要查詢資料庫,我們都知道查詢資料庫所消耗的效能更高,而記憶體比較很快.

結論:exists()適合b錶比a表資料大的情況

當a表資料與b表資料一樣大時,in與exists效率差不多,可任選乙個使用.

ORACLE in與exists的選擇

業務問題大概可以這樣描述,乙個父表,乙個子表,查詢的結果是找到子表中沒有使用父表id的記錄,這種情況估計很多系統都會牽涉得到。讓我們來舉乙個例子 表一 父表 parent 1 id varchar2 10 主鍵 2 name varchar2 100 名稱 表二 子表 childen 1 id va...

ORACLE in與exists語句的區別

業務問題大概可以這樣描述,乙個父表,乙個子表,查詢的結果是找到子表中沒有使用父表id的記錄,這種情況估計很多系統都會牽涉得到。讓我們來舉乙個例子 表一 父表 parent 表二 子表 childen 父表儲存父親,子表儲存孩子,然後通過pid和父表關聯,查詢需要的結果是找到尚未有孩子的父親。我們來看...

ORACLE in與exists語句的區別

select from a where id in select id from b 以上查詢使用了in語句,in 只執行一次,它查出b表中的所有id欄位並快取起來.之後,檢查a表的id是否與b表中的id相等,如果相等則將a表的記錄加入結果集中,直到遍歷完a表的所有記錄.它的查詢過程類似於以下過程 ...