參考文章:
1.查詢順序
exists先執行主查詢,再去子查詢中查詢與其對應的結果,如果true則輸出記錄,否則不輸出。
in先子查詢產生結果集,然後主查詢去結果集中找符合要求的字段列表,符合要求則輸出記錄,否則不輸出。
2.內外表連線方式
exists是對外表做loop迴圈,再對內表進行查詢。
in是把外表和內錶作hash連線。
3.查詢內容
in查詢的子條件返回結果必須只有乙個字段,例如select * from user where userid in(select id from b);而不能是select * from user where userid in (select id,age from b)。
exists沒有這個限制。
4.執行效率
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)select * from a where id in (select id from b);
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;i結論:in()適合b錶比a表資料小的情況
2)select * from a where exists (select 1 from b where a.id=b.id);
exists()會執行a.length次,它並不快取exists()結果集,因為exists()結果集的內容並不重要,重要的是其內查詢語句的結果集空或者非空,空則返回false,非空則返回true。
它的查詢過程類似於以下過程:
複製** **如下:
list resultset={};
array a=(select * from a);
for(int i=0;i結論:exists()適合b錶比a表資料大的情況
當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適合於外表小而內錶大的情況。
關於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)。
5.not in和not exists
not in對內外表都進行全表掃瞄,沒用到索引。
not exists的子查詢依然能用到表上的索引。
所以,無論哪個表達,用not exists都比not in要快。
sql中in和exists的區別
in是把外表和內錶作hash連線,而exists是對外表作loop迴圈,每次loop迴圈再對內表進行查詢,一直以來認為exists比in效率高的說法是不準確的。如果查詢的兩個表大小相當,那麼用in和exists差別不大 如果兩個表中乙個較小乙個較大,則子查詢表大的用exists,子查詢錶小的用in ...
SQL中in和exists的區別
in和exists in 是把外表和內錶作hash 連線,而exists是對外表作loop迴圈,每次loop迴圈再對內表進行查詢。in parm1,parm2.parm是有個數限制的 如果兩個表中乙個較小,乙個是大表,則子查詢表大的用exists,子查詢錶小的用in 例如 表a 小表 表b 大表 1...
SQL中IN和EXISTS用法的區別
not in select distinct md001 from bommd where md001 not in select mc001 from bommc not exists,exists的用法跟in不一樣,一般都需要和子表進行關聯,而且關聯時,需要用索引,這樣就可以加快速度 selec...