mysql中EXISTS和IN的使用方法比較
1、使用方式:
(1)EXISTS用法
select a.batchName,a.projectId from ucsc_project_batch a where EXISTS (select b.id from ucsc_project b where a.projectId = b.id)
上面這條SQL的意思就是:以ucsc_project_batch為主表查詢batchName與projectId字段,其中projectId字段存在于ucsc_project表中。
EXISTS 會對外表ucsc_project_batch進(jìn)行循環(huán)查詢匹配,它不在乎后面的內(nèi)表子查詢的返回值是什么,只在乎有沒有存在返回值,存在返回值,則條件為真,該條數(shù)據(jù)匹配成功,加入查詢結(jié)果集中;如果沒有返回值,條件為假,丟棄該條數(shù)據(jù)。
例如我們這里改變一下子查詢的查詢返回字段,并不影響外查詢的查詢結(jié)果:
select a.batchName,a.projectId from ucsc_project_batch a where EXISTS (select b.companyId,b.name from ucsc_project b where a.projectId = b.id)
(2)IN用法
select a.batchName,a.projectId from ucsc_project_batch a where a.projectId in (select b.id from ucsc_project b)
上面這條SQL的查詢結(jié)果與剛才的EXISTS的結(jié)果一樣,查詢的意思也一樣。
2、注意點(diǎn):
(1)EXISTS寫法需要注意子查詢中的條件語句一般需要帶上外查詢的表做關(guān)聯(lián),不然子查詢的條件可能會一直為真,或者一直為假,外查詢的表進(jìn)行循環(huán)匹配的時(shí)候,要么全部都查詢出來,要么一條也沒有。
select a.batchName,a.projectId from ucsc_project_batch a where EXISTS (select b.id from ucsc_project b)
比如上述這種寫法,由于ucsc_project 表存在值,子查詢的條件一直為真,ucsc_project_batch 每條數(shù)據(jù)進(jìn)行循環(huán)匹配的時(shí)候,都能匹配成功,查詢出來的結(jié)果就成為了ucsc_project_batch整張表數(shù)據(jù)。
select a.batchName,a.projectId from ucsc_project_batch a where EXISTS (select b.id from ucsc_project b where b.id is null)
這種寫法,子查詢肯定查不到結(jié)果,所以子查詢的條件為假,外查詢的每條數(shù)據(jù)匹配失敗,整個(gè)查詢結(jié)果為空
(2)IN語句在mysql中沒有參數(shù)個(gè)數(shù)的限制,但是mysql中SQL語句有長度大小限制,整段最大為4M
(3)EXISTS的子查詢語句不在乎查詢的是什么,只在乎有沒有結(jié)果集存在,存在則整個(gè)子查詢可以看作一個(gè)條件為真的語句,不然就是一個(gè)條件為假的語句
(4)IN語句對于子查詢的返回字段只能由一個(gè),不然會報(bào)錯(cuò):
select a.batchName,a.projectId from ucsc_project_batch a where a.projectId in (select b.id,b.companyId from ucsc_project b)
[Err] 1241 - Operand should contain 1 column(s)
3、場景選擇
外查詢表大,子查詢表小,選擇IN;外查詢表小,子查詢表大,選擇EXISTS;若兩表差不多大,則差不多。
(1)IN中的SQL查詢只會查詢一次,然后把結(jié)果集存在臨時(shí)文件中,然后再與外層查詢sql進(jìn)行匹配,其中外查詢與子查詢都可以使用索引
select a.batchName,a.projectId from ucsc_project_batch a where a.projectId in (select b.id from ucsc_project b)
等價(jià)于:
$result = []; $ucsc_project_batch = "select a.batchName,a.projectId from ucsc_project_batch a"; $ucsc_project = "select b.id from ucsc_project b"; for($i = 0;$i < $ucsc_project_batch .length;$i++){ for($j = 0;$j < $ucsc_project .length;$j++){ if($ucsc_project_batch [$i].projectId== $ucsc_project [$j].id){ $result[] = $ucsc_project_batch [$i]; break; } } }
(2)EXISTS會對外查詢的表ucsc_project_batch 進(jìn)行循環(huán)匹配,執(zhí)行ucsc_project_batch.length次,其中子查詢可以使用索引,外查詢?nèi)頀呙?/p>
select a.batchName,a.projectId from ucsc_project_batch a where EXISTS (select b.id from ucsc_project b where a.projectId = b.id)
等價(jià)于:
$result = []; $ucsc_project_batch = "select a.batchName,a.projectId from ucsc_project_batch a "; for ($i = 0; $i < $ucsc_project_batch . length; $i++) { if (exists($ucsc_project_batch [$i] . projectId)) {//執(zhí)行select b.id from ucsc_project b where a.projectId=b.id $result[] = $ucsc_project_batch [$i]; } }
通過兩個(gè)的偽代碼分析可知:子查詢的表大的時(shí)候,使用EXISTS可以有效減少總的循環(huán)次數(shù)來提升速度;當(dāng)外查詢的表大的時(shí)候,使用IN可以有效減少對外查詢表循環(huán)遍歷來提升速度。
總結(jié)
到此這篇關(guān)于mysql中EXISTS和IN的使用方法比較的文章就介紹到這了,更多相關(guān)mysql EXISTS和IN比較內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql中關(guān)于覆蓋索引的知識點(diǎn)總結(jié)
在本篇文章里小編給大家整理的是一篇關(guān)于mysql中關(guān)于覆蓋索引的知識點(diǎn)總結(jié)內(nèi)容,有需要的朋友們學(xué)習(xí)參考下。2020-08-08MySQL刪除表的時(shí)候忽略外鍵約束的簡單實(shí)現(xiàn)
下面小編就為大家?guī)硪黄狹ySQL刪除表的時(shí)候忽略外鍵約束的簡單實(shí)現(xiàn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03