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 ...