pl/sql里的exists和in的差别
項(xiàng)目中有個(gè)需要需要如下pl/sql(數(shù)據(jù)庫(kù)是MariaDB)
SELECT COUNT(1) AS small FROM cmp_ent_main a WHERE createTime<'2016-9-21'AND EXISTS(SELECT 1 FROM cmp_ent_service_config WHERE entId=a.id AND serviceType IN(2,3,4) AND STATUS=0) ;執(zhí)行時(shí)發(fā)現(xiàn)耗時(shí)近50秒,這是測(cè)試環(huán)境啊,
表cmp_ent_main,pk是id,有74836條記錄;表cmp_ent_service_config,pk是entId和serviceType,有2254條記錄,并不多。
explain看一下執(zhí)行計(jì)劃:
說(shuō)實(shí)話,mysql不熟,也并沒(méi)看出什么門(mén)道。
經(jīng)過(guò)排查原因,最后發(fā)現(xiàn)原因是cmp_ent_service_config表的entId是varchar, entId是企業(yè)Id,這個(gè)系統(tǒng)里約定的企業(yè)Id是bigint??磥?lái)做這個(gè)模塊的設(shè)計(jì)者忽略了這一點(diǎn)就設(shè)置成varchar了。
改成bigint,果然,毫秒級(jí)就查出結(jié)果了。類(lèi)型一致多么的重要!
?
我找到這個(gè)模塊的開(kāi)發(fā)擔(dān)當(dāng),他習(xí)慣用in,于是改成in,并恢復(fù)entId的類(lèi)型為varchar,發(fā)現(xiàn)也是毫秒級(jí)出結(jié)果。
EXPLAINSELECT COUNT(1) AS small FROM cmp_ent_main a WHERE createTime<'2016-9-21'AND EXISTS(SELECT 1 FROM cmp_ent_service_config WHERE entId=a.id AND serviceType IN(2,3,4) AND STATUS=0) ;EXPLAINSELECT 0 allcount, COUNT(1) AS small FROM cmp_ent_main a WHERE createTime<'2016-9-21'AND a.id IN(SELECT entId FROM cmp_ent_service_config WHERE serviceType IN(2,3,4) AND STATUS=0)細(xì)看兩者的查詢計(jì)劃,發(fā)現(xiàn)主要的區(qū)別是cmp_ent_main的記錄數(shù),一個(gè)是70303,一個(gè)是1
當(dāng)把entId的類(lèi)型改為bigint后, 兩者的執(zhí)行計(jì)劃是:
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/buguge/p/5854325.html
總結(jié)
以上是生活随笔為你收集整理的pl/sql里的exists和in的差别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 3_STL算法
- 下一篇: php每天一题:strlen()与mb_