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