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

原文地址:https://www.cnblogs.com/hider/p/10039089.html