成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

mysql中exists和in的區(qū)別是什么

今天就跟大家聊聊有關(guān)MySQL中exists 和in的區(qū)別是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

成都創(chuàng)新互聯(lián)于2013年創(chuàng)立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目成都網(wǎng)站建設(shè)、成都做網(wǎng)站網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元陸豐做網(wǎng)站,已為上家服務(wù),為陸豐各地企業(yè)和個人服務(wù),聯(lián)系電話:028-86922220

MySQL中in和exists的性能優(yōu)劣以及各自的檢索數(shù)據(jù)的過程 ,以下面的語句為例子:

select * from user a where name='liuwenhe' and exists (select stuid from department b where depname='yunwei' and a.stuid =b.stuid );

select * from user where name='liuwenhe' and stuid in (select stuid from department where depname='yunwei');

MySQL exists和in檢索數(shù)據(jù)的過程:

1.首先說下exists檢索過程,

注意其中A代表(user a where name='liuwenhe')的結(jié)果集,B代表(department b where depname='yunwei' )的結(jié)果集:

exists對外表A用loop逐條查詢,每次查詢都會去驗證exists的條件語句(也就是exists后面括號里面的語句),當 exists里的條件語句能夠返回記錄行時(只要能返回結(jié)果即可,不管你查詢的是什么內(nèi)容!!!),條件就為真,就會返回當前l(fā)oop到的A的這條記錄,反之如果exists里的條件語句不能返回記錄行,條件為假,則當前l(fā)oop到的A的這條記錄被丟棄,注意:exists的條件就像一個bool條件,當能返回結(jié)果集則為true,不能返回結(jié)果集則為 false;

對于exists的檢索過程可以用下面的腳本概括:

for ($i = 0; $i < count(A); $i++) {

$a = get_record(A, $i); #從A表逐條獲取記錄

if (B.id = $a[id]) #如果子條件成立,即返回true

$result[] = $a;   }

return $result;

例如:

select * from user where exists (select stuid from department where depname='yunwei' );

對user表的記錄逐條取出,由于exists條件中的select stuid from department where depname='yunwei' 永遠能返回記錄行,那么user表的所有記錄都將被加入結(jié)果集,所以與 select * from user;是一樣的

例如:

select * from user where exists (select stuid from department where depname='yunwei+' );

not exists與exists相反,也就是當exists條件有結(jié)果集返回時,loop到的記錄將被丟棄,否則將loop到的記錄加入結(jié)果集

總的來說,如果user表結(jié)果集有n條記錄,那么exists查詢就是將這n條記錄逐條取出,然后判斷n遍exists條件 。

2.關(guān)于in子查詢的檢索過程:

MySQL先將子查詢結(jié)果存入臨時表T(可能在內(nèi)存中,也可能磁盤中),確保子查詢只執(zhí)行一次,該表不記錄重復(fù)數(shù)據(jù)且采用哈希索引遍歷數(shù)據(jù),然后通過T表的數(shù)據(jù)去遍歷外表,通過關(guān)聯(lián)關(guān)系得到外表的需要的數(shù)據(jù),in查詢相當于多個or條件的疊加,這個比較好理解,比如下面的查詢

select * from user where userId in (1, 2, 3);

等效于

select * from user where userId = 1 or userId = 2 or userId = 3;

not in與in相反,如下

select * from user where userId not in (1, 2, 3);

等效于

select * from user where userId != 1 and userId != 2 and userId != 3;

總的來說,in查詢就是先將子查詢條件的記錄全都查出來,假設(shè)結(jié)果集為B,共有m條記錄,

然后在將子查詢條件的結(jié)果集分解成m個,再進行m次主查詢,值得一提的是,in查詢的子條件返回結(jié)果必須只有一個字段,例如

select * from user where userId in (select id from B);

而不能是

select * from user where userId in (select id, age from B);

而exists就沒有這個限制

exists和in的性能

select * from user a where name='liuwenhe' and exists (select stuid from department b where depname='yunwei' and a.stuid =b.stuid );

select * from user where name='liuwenhe' and stuid in (select stuid from department where depname='yunwei');

1)根據(jù)前面介紹的檢索數(shù)據(jù)的過程,可以知道,針對上面的兩條sql中exists這種方式,是需要遍歷user表name='liuwenhe'的所有數(shù)據(jù)行N,并且判斷exists條件N次;并且如果department表的stuid 有索引,exists子查詢可以使用連接關(guān)系(也就是stuid)上的索引;所以exists方式適合 user表的結(jié)果集小,子查詢的結(jié)果集大的情況; 子查詢可以使用關(guān)聯(lián)關(guān)系列上的索引,所以效率高,故內(nèi)表大的適合使用exists;

2)not exists類似于exists的遍歷方式,也是loop外表,然后判斷exists條件

3)in是把外表user結(jié)果集和內(nèi)表department結(jié)果集做hash連接(應(yīng)該說類似hash join,因為MySQL不支持hash join的方式),先查詢內(nèi)表department結(jié)果集,再把內(nèi)表結(jié)果集與外表結(jié)果集匹配,對外表可以使用關(guān)系索引(也就是stuid列上的索引),而內(nèi)表結(jié)果集多大都需要查詢,也就是說department where depname='yunwei'的結(jié)果集D多大,都得遍歷全部的D,不可避免,故外表大的使用in,可加快效率。 主查詢可以使用關(guān)聯(lián)關(guān)系列上的索引,所以效率高,故外表結(jié)果集合大的適合使用in;

3)如果用not in ,和in一樣,內(nèi)表結(jié)果集需要全部掃描,由于not in ,所以外表的結(jié)果集也需要權(quán)標掃描,都無法使用關(guān)系列上的索引(這種!=的范圍查詢無法使用任何索引),效率低,可考慮使用not exists,也可使用A left join B on A.id=B.id where B.id is null 進行優(yōu)化。

總結(jié):

exists先對外表結(jié)果集loop循環(huán)再對內(nèi)表結(jié)果集進行查詢。一直大家都認為exists比in語句的效率要高,這種說法其實是不準確的。這個是要區(qū)分環(huán)境的。如果查詢的兩個表大小相當,那么用in和exists差別不大。 如果兩個表中一個較小,一個是大表,則子查詢表結(jié)果集大的用exists,如果外表結(jié)果集大的則適合使用in,然后就是網(wǎng)絡(luò)中說的外表的和內(nèi)表大的說法也不準確,應(yīng)該是外表結(jié)果集和內(nèi)表結(jié)果集合的大小,至于結(jié)果集前面已經(jīng)解釋過了。

看完上述內(nèi)容,你們對mysql中exists 和in的區(qū)別是什么有進一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。

分享題目:mysql中exists和in的區(qū)別是什么
網(wǎng)頁路徑:http://jinyejixie.com/article4/jjjjie.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、品牌網(wǎng)站建設(shè)面包屑導(dǎo)航、企業(yè)網(wǎng)站制作、定制開發(fā)、外貿(mào)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)
年辖:市辖区| 鲁甸县| 闽清县| 阜城县| 大冶市| 汪清县| 永定县| 鄂伦春自治旗| 武穴市| 上虞市| 中卫市| 广汉市| 新沂市| 拉萨市| 宣化县| 咸丰县| 富源县| 南召县| 聂拉木县| 济南市| 崇阳县| 天峨县| 新和县| 承德县| 南和县| 扶余县| 溧阳市| 无锡市| 武乡县| 山阴县| 罗城| 楚雄市| 马龙县| 高唐县| 即墨市| 安泽县| 乌鲁木齐县| 达尔| 海南省| 鱼台县| 游戏|