• Oracle学习笔记:a inner join b与from a,b where a.x=b.x的差异


      近期,在使用Oracle的过程中,由以下两段代码的执行引发的思考,到底 select * from a,b where a.id = b.idselect * from a inner join b on a.id = b.id 有没有区别?

    ----- 代码1 ----
    select a.xxx, b.xxx, c.xxx 
    from BUSI_SQJS a,BUSI_SLSH b,BUSI_XSSC c,BUSI_SCJD d,BUSI_ZJQF e,BUSI_ZJBFSD f
    where substr(a.HANDLERDAVARTE,1,10) between '2018-01-01' and '2018-11-14'
    and a.PROCESS_NUM=b.PROCESS_NUM
    and a.PROCESS_NUM=c.PROCESS_NUM
    and a.PROCESS_NUM=d.PROCESS_NUM
    and a.PROCESS_NUM=e.PROCESS_NUM
    and a.PROCESS_NUM=f.PROCESS_NUM;
    
    ---- 代码2 ----
    select /*+parallel(a,10)*/ a.SQRLX,a.SQRMC,a.SQRSFZMWJ,a.CARDID,a.SQRLXDH,
           a.SQRLXDZ,a.SDFS,a.SQJSYJ,a.HAS_SPCL,a.HAS_CLBZ,
           e.ZJBH,f.SDFS,a.SQJSJG,b.SQSLJG,c.SQCLXSSCJG,
           d.SCJDSCJG 
    from BUSI_SQJS a
    left join BUSI_SLSH b on a.PROCESS_NUM=b.PROCESS_NUM
    left join BUSI_XSSC c on a.PROCESS_NUM=c.PROCESS_NUM
    left join BUSI_SCJD d on a.PROCESS_NUM=d.PROCESS_NUM
    left join BUSI_ZJQF e on a.PROCESS_NUM=e.PROCESS_NUM
    left join BUSI_ZJBFSD f on a.PROCESS_NUM=f.PROCESS_NUM
    where a.HANDLERDAVARTE >= to_date('2018-01-01','yyyymmdd')
    and a.HANDLERDAVARTE <= to_date('2018-11-14','yyyymmdd');

      经过好一番查资料验证,最后更加迷惑。。。

      ……

      ……

      有一说法:inner join优于where多表查询

      另一说法:where a,b 默认就是内连接 inner join

      join 方式的 on 指向连接条件,而其后的 where 条件是筛选连接条件产生的结果集,即先按连接条件连接两表,后根据条件进行筛选。

      inner join 与一般笛卡尔积的区别:inner join是笛卡尔积的特殊形式。如果有表a和表b,表a有m条记录,表b有n条记录,则一般笛卡尔积后得到的记录条数是m*n条,记录之间的组合是随意的。而内连接则是建立在表a和表b的结构中有相同的列名的基础上进行的。

      单纯的select * from a,b是笛卡尔乘积。

      但是,如果对两个表进行关联:select * from a,b where a.id = b.id 就变了,此时就等价于:select * from a inner join b on a.id = b.id,即内连接。

      ……

      ……

      最后,不得已,还是得亲自动手实验。。。

    select * from temp_cwh_1128 -- 1275188
    select * from mobile.tb_mr_prod_obj@recom -- 1274
    ---- 1.建立测试表 ----
    create table temp_cwh_1128 as
    select * from table_xxx a 
    where a.target_id='764'
    ---- 2.inner join 测试 ---- 4s
    select b.prod_code, count(distinct a.account_id)
    from temp_cwh_1128 a
    inner join mobile.tb_mr_prod_obj@recom b
    on a.prod_id = b.prod_id
    group by b.prod_code
    order by b.prod_code;
    ---- 3.多表连接测试 ---- 4s
    select b.prod_code, count(distinct a.account_id)
    from temp_cwh_1128 a, mobile.tb_mr_prod_obj@recom b
    where a.prod_id = b.prod_id 
    group by b.prod_code
    order by b.prod_code;

      查看解释计划,两种测试方式的执行过程应该是一致的。

      结论来了!!!

      1.等值连接,不加where条件的时候会产生笛卡尔积,尤其是多表进行连接的时候,产生的笛卡尔积不可预料;但是加上条件a.id = b.id之后,与内连接inner join的效率是一样的,所以“代码1”中的方式理论上来说并没有什么问题;

      2.内连接本质上也是将多表关联之后,筛选满足条件的行;

      3.where a,b的写法不符合规范,最好写成inner join的写法。


    END 2018-11-29 16:44:49

  • 相关阅读:
    gRPC错误码 http状态码 provide your APIs in both gRPC and RESTful style at the same time
    rust
    lz4 1
    剖析美团内部所采用的网站压力测试方案
    【NOIP2002提高组T4】矩形覆盖-DFS剪枝
    【NOIP2002提高组T4】矩形覆盖-DFS剪枝
    【POJ2777】Count Color-线段树区间更新
    【POJ2777】Count Color-线段树区间更新
    【NOIP2005提高组T3】篝火晚会-置换群
    【NOIP2005提高组T3】篝火晚会-置换群
  • 原文地址:https://www.cnblogs.com/hider/p/10039089.html
Copyright © 2020-2023  润新知