SQL查詢中in和exists的區別分析

2021-09-02 10:31:19 字數 2855 閱讀 6641

sql查詢中in和exists的區別分析

如果是exists,那麼以外層表為驅動表,先被訪問,如果是in,那麼先執行子查詢,所以我們會以驅動表的快速返回為目標

select * from a where id in (select id from b);

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

對於以上兩種情況,in是在記憶體裡遍歷比較,而exists需要查詢資料庫,所以當b表資料量較大時,exists效率優於in。

1、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;ireturn resultset;

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

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

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

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

2、exists()語句內部工作原理

exists()會執行a.length次,它並不快取exists()結果集,因為exists()結果集的內容並不重要,重要的是其內查詢語句的結果集空或者非空,空則返回false,非空則返回true。

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

list resultset={};

array a=(select * from a);

for(int i=0;i}return resultset;

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

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

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

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

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

3、使用情況分析

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

在插入記錄前,需要檢查這條記錄是否已經存在,只有當記錄不存在時才執行插入操作,可以通過使用 exists 條件句防止插入重覆記錄。

insert into a (name,age) select name,age from b where not exists (select 1 from a where a.id=b.id);

exists與in的使用效率的問題,通常情況下採用exists要比in效率高,因為in不走索引。但要看實際情況具體使用:

in適合於外表大而內錶小的情況;

exists適合於外表小而內錶大的情況。

4、關於exists:

exists用於檢查子查詢是否至少會返回一行資料,該子查詢實際上並不返回任何資料,而是返回值true或false。

exists 指定乙個子查詢,檢測行的存在。

語法: exists subquery

引數: subquery 是乙個受限的 select 語句 (不允許有 compute 子句和 into 關鍵字)。

結果型別: boolean 如果子查詢包含行,則返回 true ,否則返回 flase 。

結論:select * from a where exists (select 1 from b where a.id=b.id)

exists(包括 not exists )子句的返回值是乙個boolean值。 exists內部有乙個子查詢語句(select ... from...),我將其稱為exist的內查詢語句。其內查詢語句返回乙個結果集, exists子句根據其內查詢語句的結果集空或者非空,返回乙個布林值。

一種通俗的可以理解為:將外查詢表的每一行,代入內查詢作為檢驗,如果內查詢返回的結果取非空值,則exists子句返回true,這一行行可作為外查詢的結果行,否則不能作為結果。

分析器會先看語句的第乙個詞,當它發現第乙個詞是select關鍵字的時候,它會跳到from關鍵字,然後通過from關鍵字找到表名並把表裝入記憶體。接著是找where關鍵字,如果找不到則返回到select找欄位解析,如果找到where,則分析其中的條件,完成後再回到select分析字段。最後形成一張我們要的虛表。

where關鍵字後面的是條件表示式。條件表示式計算完成後,會有乙個返回值,即非0或0,非0即為真(true),0即為假(false)。同理where後面的條件也有乙個返回值,真或假,來確定接下來執不執行select。

分析器先找到關鍵字select,然後跳到from關鍵字將student表匯入記憶體,並通過指標找到第一條記錄,接著找到where關鍵字計算它的條件表示式,如果為真那麼把這條記錄裝到乙個虛表當中,指標再指向下一條記錄。如果為假那麼指標直接指向下一條記錄,而不進行其它操作。一直檢索完整個表,並把檢索出來的虛擬表返回給使用者。exists是條件表示式的一部分,它也有乙個返回值(true或false)。

**(

SQL查詢中in和exists的區別

sql查詢中in和exists的區別分析 select from a where id in select id from b select from a where exists select 1 from b where a.id b.id 對於以上兩種情況,in是在記憶體裡遍歷比較,而exis...

SQL查詢中in和exists的區別分析

先上 select from a where id in select id from b select from a where exists select 1from b where a.id b.id 對於以上兩種情況,in是在記憶體裡遍歷比較,而exists需要查詢資料庫,所以當b表資料量較...

SQL查詢中in和exists的區別分析

本文出處參考 url select from a where id in select id from b select from a where exists select 1 from b where a.id b.id 對於以上兩種情況,in是在記憶體裡遍歷比較,而exists需要查詢資料庫,...