IN和EXISTS執(zhí)行順序不一樣。
IN先執(zhí)行后面的子查詢,再執(zhí)行外部查詢,而EXISTS先執(zhí)行前面的外部查詢,再根據(jù)外部查詢結(jié)果依次進(jìn)行子查詢。
EXISTS:存在。
EXISTS(xxxxx)后面的子查詢被稱做相關(guān)子查詢,它是不返回列表的值的,只返回一個(gè)TRUE或FALSE的結(jié)果。
先運(yùn)行前面的主查詢(外部查詢),根據(jù)主查詢的結(jié)果依次去相關(guān)子查詢里查詢,如果存在就返回TRUE并輸出,反之返回FALSE且不輸出,最后使用子查詢的結(jié)果來確定外部查詢的結(jié)果集。
例如外部查詢返回100行,SQL 就將執(zhí)行101次查詢——一次執(zhí)行外部查詢,然后為外部查詢返回的每一行執(zhí)行一次子查詢。
IN:包含。
IN()后面的子查詢是返回結(jié)果集的,子查詢先產(chǎn)生結(jié)果集,然后主查詢?cè)偃ソY(jié)果集里去找符合要求的字段列表,符合要求的輸出,反之則不輸出。
NOT IN的執(zhí)行順序:在表中一條記錄一條記錄的查詢(查詢每條記錄),符合要求的就返回結(jié)果集,不符合的就繼續(xù)查詢下一條記錄,直到把表中的記錄查詢完。也就是說為了證明找不到,所以只能查詢?nèi)坑涗洸拍茏C明,并沒有用到索引。
NOT EXISTS的執(zhí)行順序:根據(jù)索引查詢,如果存在就返回TRUE,如果不存在就返回FALSE,不會(huì)每條記錄都去查詢。
A表為前面的主查詢,B表為后面的子查詢。
當(dāng)B表數(shù)據(jù)較大時(shí)不適合使用IN(),因?yàn)樗鼤?huì)把B表數(shù)據(jù)全部遍歷一次,IN()適合B表比A表數(shù)據(jù)小的情況。當(dāng)B表比A表數(shù)據(jù)大時(shí)適合使用EXISTS(),因?yàn)樗鼪]有那么遍歷操作,只需要再執(zhí)行一次查詢就行。
EXISTS()結(jié)果集并不緩存,因?yàn)镋XISTS()結(jié)果集的內(nèi)容并不重要,重要的是結(jié)果集中是否有記錄,如果有則返回TRUE,沒有則返回FALSE。
如果A表有10000條記錄,B表有1000000條記錄,那么EXISTS()會(huì)執(zhí)行10000次去判斷A表中的id是否與B表中的id相等??梢夿表數(shù)據(jù)越多,越適合EXISTS()發(fā)揮效果。
總結(jié):
IN和EXISTS執(zhí)行順序不一樣,通常情況下EXISTS比IN的效率高,因?yàn)镋XISTS走索引,而IN不走索引,不過IN()是在內(nèi)存里遍歷比較,而EXISTS()需要查詢數(shù)據(jù)庫(查詢數(shù)據(jù)庫所消耗的性能更高,內(nèi)存比較快),因此要看實(shí)際情況來選擇使用:IN()適合于外表大而內(nèi)表小的情況;EXISTS()適合于外表小而內(nèi)表大的情況;當(dāng)兩者數(shù)據(jù)一樣大時(shí),IN與EXISTS效率差不多,可任選一個(gè)使用。