in和exists過程對比

二者執行流程徹底不同。html

in的過程

select * from tableA a where a.id in (select b.a_id from tableB b);sql

1)首先子查詢,查詢B表中全部的 aid,結果集 listB。spa

2)進行外查詢,結果集 listA。htm

3)listA 和 listB 取笛卡爾積,即有 listA.len*listB.len 條記錄。根據 a.id=b.a_id 對笛卡爾積結果進行篩選。blog

  for(t : listA.len*listB.len){索引

    if(t.id == t.aid) {get

      list.add(t);io

    }table

  }效率

  retrun list;

因此,in的效率取決於in子查詢。

exists的過程

select * from tableA a where exists (select 1 from tableB b where a.id=b.a_id);

1)外查詢,這裏是select * from tableA a,結果集 listA。

2)對 listA 的 a.id 進行 exists 篩選。

  for(a : listA.length){

    if( (select 1 from tableB b where b.a_id=a.id) != null ) {

      list.add(a);

    }

  }

  retrun list;

因此,exists的效率取決於外查詢.

總結

當子查詢的結果集相對很大時,不要用 in, 避免笛卡爾積。

通常, 除非子查詢結果集很小(好比字典),不然都優先使用exists ??.

 

not in 和 not exists

雖然「通常狀況下,使用exists比使用in更好」的說法不必定準確,

可是「通常狀況下,使用 not exists 比使用 not in 更好」的說法是沒問題的。

使用 not in 會對外表和內表進行全表掃描,會忽略掉索引;

使用not exists的子查詢能夠使用表的索引的。

 

參考:

https://www.cnblogs.com/liyasong/p/sql_in_exists.html

相關文章
相關標籤/搜索