MySQL中in和exists區(qū)別詳解
一、提前準備
為了大家學習方便,我在這里面建立兩張表并為其添加一些數(shù)據(jù)。
一張水果表,一張供應(yīng)商表。
水果表 fruits表
f_id | f_name | f_price |
---|---|---|
a1 | apple | 5 |
a2 | appricot | 2 |
b1 | blackberry | 10 |
b2 | berry | 8 |
c1 | cocount | 9 |
供應(yīng)商表 suppliers表
s_id | s_name |
---|---|
101 | 天虹 |
102 | 沃爾瑪 |
103 | 家樂福 |
104 | 華潤萬家 |
我們將用這兩張表做演示。
二、什么是exists
exists
關(guān)鍵字后面的參數(shù)是一個任意的子查詢,系統(tǒng)對子查詢進行運算以判斷它是否返回行,如果至少返回一行,那么exists
的結(jié)果為true
,此時外層的查詢語句將進行查詢;如果子查詢沒有返回任何行,那么exists
的結(jié)果為false
,此時外層語句將不進行查詢。
需要注意的是,當我們的子查詢?yōu)?SELECT NULL
時,MYSQL仍然認為它是True
。
三、什么是in
in 關(guān)鍵字進行子查詢時,內(nèi)層查詢語句僅僅返回一個數(shù)據(jù)列,這個數(shù)據(jù)列的值將提供給外層查詢語句進行比較操作。
為了測試in 關(guān)鍵字,我在水果表中加了s_id一列
水果表 fruits表
f_id | f_name | f_price | s_id |
---|---|---|---|
a1 | apple | 5 | 101 |
a2 | appricot | 2 | 103 |
b1 | blackberry | 10 | 102 |
b2 | berry | 8 | 104 |
c1 | cocount | 9 | 103 |
四、exists和in
in和exists到底有啥區(qū)別那,要什么時候用in,什么時候用exists?
我們先記住口訣再說細節(jié)!“外層查詢表小于子查詢表,則用exists,外層查詢表大于子查詢表,則用in,如果外層和子查詢表差不多,則愛用哪個用哪個。”
我想你已經(jīng)看出來了,當fruits表數(shù)據(jù)很大的時候不適合用in,因為它最多會將fruits表數(shù)據(jù)全部遍歷一次。
如:suppliers表有10000條記錄,fruits表有1000000條記錄,那么最多有可能遍歷10000*1000000次,效率很差。
再如:suppliers表有10000條記錄,fruits表有100條記錄,那么最多有可能遍歷10000*100次,遍歷次數(shù)大大減少,效率大大提升。
但是:suppliers表有10000條記錄,fruits表有100條記錄,那么exists()還是執(zhí)行10000次,還不如使用in()遍歷10000*100次,因為in()是在內(nèi)存里遍歷,而exists()需要查詢數(shù)據(jù)庫,我們都知道查詢數(shù)據(jù)庫所消耗的性能更高,而內(nèi)存比較很快。
因此我們只需要記住口訣:“外層查詢表小于子查詢表,則用exists,外層查詢表大于子查詢表,則用in,如果外層和子查詢表差不多,則愛用哪個用哪個。”
五、not exists和not in
和exists一樣,用到了suppliers上的id索引,exists()執(zhí)行次數(shù)為fruits.length,不緩存exists()的結(jié)果集。
因為not in實質(zhì)上等于!= and != ···
,因為!=不會使用索引,故not in不會使用索引。
為啥not in不會使用索引?
我們假設(shè)有100萬數(shù)據(jù),s_id只有0和1兩個值,利用索引我們要先讀索引文件,然后二分查找,找到對應(yīng)的數(shù)據(jù)磁盤指針,再根據(jù)讀到的指針在磁盤上對應(yīng)的數(shù)據(jù),影響結(jié)果集50萬,這種情況,和直接全表掃描哪個快顯而易見。
如果你s_id字段是一個unique,就會用到索引。
如果你一定要用索引,可以用force index,不過效率不會有改善一般還會更慢就是了。
合理使用索引,Cardinality是一個重要指標,太小的話跟沒建沒區(qū)別,還浪費空間。
因此,不管suppliers和fruits大小如何,均使用not exists效率會更高。
到此這篇關(guān)于MySQL中in和exists區(qū)別詳解的文章就介紹到這了,更多相關(guān)MySQL in和exists區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql復(fù)制data文件遷移的實現(xiàn)步驟
有時候,我們需要遷移整個數(shù)據(jù)庫,包括數(shù)據(jù)文件,本文將介紹如何通過復(fù)制MySQL的data文件來完成數(shù)據(jù)庫遷移,具有一定的參考價值,感興趣的可以了解一下2023-11-11MySql狀態(tài)查看方法 MySql如何查看連接數(shù)和狀態(tài)?
如果是root帳號,你能看到所有用戶的當前連接。如果是其它普通帳號,只能看到自己占用的連接2012-11-11MySQL中的log_bin_trust_function_creators系統(tǒng)變量
本文主要介紹了MySQL中的log_bin_trust_function_creators系統(tǒng)變量,log_bin_trust_function_creators是一個全局系統(tǒng)變量,下面就來介紹一下具體使用,感興趣的可以了解一下2024-09-09mySQL中in查詢與exists查詢的區(qū)別小結(jié)
最近被一個朋友問到mySQL中in查詢和exists的區(qū)別,當然只是草草的回答了下,今天偶然看到了一篇關(guān)于mysql中的exists查詢的文章,讀完感覺太”冷落”它了,這里總結(jié)一下,也跟自己常用的in查詢做一下對比。有需要的朋友們可以參考借鑒,下面來一起學習學習吧。2016-11-11mysql數(shù)據(jù)庫批量復(fù)制單條數(shù)據(jù)記錄
在開發(fā)數(shù)據(jù)庫應(yīng)用時,批量操作是一項常見的需求,無論是數(shù)據(jù)遷移、備份還是更新,理解如何在MySQL中批量復(fù)制單條數(shù)據(jù)都至關(guān)重要,本文將深入探討這一過程,并提供代碼示例,幫助你更好地理解這一概念2025-02-02SQL?ALTER?TABLE語句靈活修改表結(jié)構(gòu)和數(shù)據(jù)類型
這篇文章主要介紹了SQL?ALTER?TABLE語句靈活修改表結(jié)構(gòu)和數(shù)據(jù)類型,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12