關於oracle中in和exists的效率 發布於 1 年前 (2018年12月20日) – 1602 次檢閱

自從工作後一直聽到老大們對我說盡量用exists不要用in,因為exists只判斷存在而in需要對比值,所以exists比較快,然後和同事打賭還輸過一杯奶茶(心疼)。但看了看網上的一些東西才發現這種比較需要分情況噠…

  • 使用in方式
  • 使用exists方式
  • 普通連表方式

1.使用in方式

select * from A where id in (select id from B)--使用in方式執行的過程相當於:  select * from A, ( select distinct id from B ) B where A.id = B.id;

2.使用exists方式

select * from A where exists(select B.id from B where B.id=A.id)--使用exists方式執行的過程相當於:  for x in ( select * from A )  loop  if ( exists ( select null from B where B.id = A.id )  then  OUTPUT THE RECORD  end if  end loop

3.普通連表方式

select A.*,B.* from A,B where A.id = B.id --普通連表方式使用笛卡爾乘積

具體使用時到底選擇哪一個,主要需要考慮查詢效率問題:

第一條語句使用了A表的索引;

第二條語句使用了B表的索引;

第三條語句同時使用了A表、B表的索引;

如果A、B表的數據量不大,那麼這三個語句執行效率幾乎無差別;

如果A表數據量大,B表小,顯然第一條語句效率更高,反之,則第二條語句效率更高;

第三條語句儘管同時使用了A表、B表的索引,單掃描次數是笛卡爾乘積,效率最差。(hive上我是這樣用的,因為使用多個欄位是不支援)

即:

IN 是把外表和內表做hash連接,而exists是對外表做loop循環,每次loop循環再對內表進行查詢

如果查詢的兩個表大小相當,那麼用in和exists差別不大。

如果兩個表一個較小,一個較大,則子查詢表大的用exists,子查詢表小的用in

not in 和not exists:

如果查詢語句使用了not in 那麼內外表都進行全表掃描,沒有用到索引;

而not exists 的子查詢依然能用到表上的索引,所以無論那個表大,用not exists都比not in要快