SQL中EXISTS與IN的使用及效率

2021-10-03 03:37:12 字數 2806 閱讀 6214

in 和exists

對於以上兩種查詢條件,in是把外表和內錶作hash 連線,而exists 是對外表作loop 迴圈,每次loop 迴圈再對內表進行查詢。

一直以來認為exists 比in 效率高的說法是不準確的。在不同的情況下,exists與in的效能各有優缺項,如果查詢的兩個表大小相當,那麼用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);

1、in的應用原理

在select * from a where id in(select id from b); 中,in()中的子查詢只執行一次,它查詢出b表中的所有id值並快取起來;之後,在記憶體中檢查a表的id是否與b表中的id值相等,如果相等則則將a表的記錄加入到結果集中,直到遍歷完a表中的所有記錄。

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

array a=;

array b=;

for (int i=0;i複製**

複製**

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

a表有10000條記錄,b表有100條記錄,那麼使用in最多可能有10000*100次遍歷,遍歷次數大大減少,效率大大提公升;

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

2、exists的應用原理

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

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

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

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

array a=(select * from a);

for(int i=0;ireturn 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效率差不多,可任選乙個使用。

資料從乙個表往另外乙個表中插入資料時使用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適合於外表小而內錶大的情況。

關於exists:

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

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。

好文要頂 關注我 收藏該文

SQL中 IN 與 EXISTS的使用

大家在談到sql優化時,都會說到用exists 代替 in 查詢。現在就談談這兩個的用法。in查詢相當於多個or條件的疊加,這個比較好理解,比如下面的查詢 select from user where userid in 1 2,3 等效於 select from user where userid...

SQL中IN與EXISTS用法的區別

結論為 in 適合b錶比a表資料小的情況 exists 適合b錶比a表資料大的情況 當a表資料與b表資料一樣大時,in與exists效率差不多,可任選乙個使用.舉例 select from emp 基礎表 where empno 0 and exists select x from dept whe...

SQL中EXISTS的使用

網上有一些關於exists 說明的例子,但都說的不是很詳細.比如對於著名的供貨商資料庫,查詢 找出 所有零件的 商的 商名,對於這個查詢,網上一些關於exists的說明文章都不能講清楚.我先解釋本文所用的資料庫例子,供貨商 資料庫,共3個表.供貨商表 s s sname 貨物表 p p pname ...