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


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM