oracle中的exists 和not exists 用法
測試用表A_使用者表(test_table_A):
1.exists操作
select *
from test_table_A A
where exists(
select 1
from test_table_B
where owner = A.A_id);
1執行結果:
分步看其執行原理為:
1> 從表A中第一條資料1001 tom開始,進入exsits函式,獲取表B中第一條資料2001 1002 cup,判斷(B.owner = A.A_id)是否為true,此處為false,因此獲取表B中第二條資料2002 1001 car,判斷(B.owner = A.id)是否為true,此處為true,則顯示錶A中第一條資料,不繼續與表B中第三條資料做判斷。
2> 從表A中第二條資料1002 jack開始,進入exsits函式,獲取表B中第一條資料2001 1002 cup,判斷(B.owner = A.A_id)是否為true,此處為ture,則顯示A中第二條資料,不繼續與表B中後續資料做判斷。
3> 從表A中第三條資料1003 jenny開始,進入exsits函式,獲取表B中第一條資料2001 1002 cup,判斷(B.owner = A.A_id)為false,獲取表中第二條資料2002 1001 car,判斷(B.owner = A.id)為false,獲取表B中第三條資料2003 1002 computer,判斷(B.owner = A.id)為false,至此已與表B中所有資料判斷完畢,均為false,因此最終結果不顯示該語句。
2.not exists
select *
from test_table_A A
where not exists(
select 1
from test_table_B
where owner = A.A_id);
執行結果:
not exists操作即為反過來,當遇到true則不顯示,全為false則顯示。
3.exists與in的效率問題
使用EXISTS,會首先檢查主查詢,然後執行子查詢,當子查詢找到第一個匹配項時即開始下一次操作。
使用IN,會先執行子查詢,並將獲得的結果列表存放在一個加了索引的臨時表中,再執行主查詢與臨時表運算。
結論:
1> select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ;
當T1資料量小而T2資料量非常大時(T1 << T2),即子查詢更耗費時間時,exists的查詢效率更高。
當T1資料量非常大而T2資料量小時(T1 >> T2),即主查詢更耗費時間時,in 的查詢效率高。