zoukankan      html  css  js  c++  java
  • 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后, 两者的执行计划是:

     

  • 相关阅读:
    MVC应用程序使用Entity Framework
    @Styles的nameSpace是什么
    创建第一个MVC应用程序
    计算DataTable某列的值(SUM)
    DropDownList 控件的SelectedIndexChanged事件触发不了
    在类中使用Response.Redirect()方法
    控制某个panel的display样式
    获取指定日期下个月份的第一天
    字符串如何还原为中文
    判断字符串中包含3个连续(升、降)或相同的数字
  • 原文地址:https://www.cnblogs.com/buguge/p/5854325.html
Copyright © 2011-2022 走看看