首页 > 代码库 > pl/sql里的exists和in的差别
pl/sql里的exists和in的差别
项目中有个需要需要如下pl/sql(数据库是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) ;
执行时发现耗时近50秒,这是测试环境啊,
表cmp_ent_main,pk是id,有74836条记录;表cmp_ent_service_config,pk是entId和serviceType,有2254条记录,并不多。
explain看一下执行计划:
说实话,mysql不熟,也并没看出什么门道。
经过排查原因,最后发现原因是cmp_ent_service_config表的entId是varchar, entId是企业Id,这个系统里约定的企业Id是bigint。看来做这个模块的设计者忽略了这一点就设置成varchar了。
改成bigint,果然,毫秒级就查出结果了。类型一致多么的重要!
我找到这个模块的开发担当,他习惯用in,于是改成in,并恢复entId的类型为varchar,发现也是毫秒级出结果。
EXPLAIN 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) ;EXPLAIN SELECT 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)
细看两者的查询计划,发现主要的区别是cmp_ent_main的记录数,一个是70303,一个是1
当把entId的类型改为bigint后, 两者的执行计划是:
pl/sql里的exists和in的差别
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。