? ? 在寫sql時,在多表關聯時,有時候容易把關聯關系寫錯。一般情況下,該問題比較容易發現,但如果sql較長時,光靠眼力就比較難發現了。今天寫了一個腳本,碰到該問題了。
? ? 第一版本的腳本如下:
?
select detail.commityear,
detail.commitmonth,
to_char((sysdate - 1), 'YYYYMM') statmonthid,
policy.corppkno,
product.prdtsubcatpkno,
product.pkno,
sum(loss_d.losssum) lossSum_FASH,
sum(claim_d.claimsum) claimSum_FASH,
sum(indemnity_d.indemnityRptDetail) indemnityRpt_FASH,
sum(recovery_d.recoverySumDetail) recoveryRpt_FASH
from F_T_DeclareDetail detail
join stdw.d_t_policy policy
on detail.policypkno = policy.pkno
join stdw.d_t_producttype product
on policy.policytypepkno = product.pkno
left join (select t.declaredetailpkno,
sum(nvl(t.losssumdetail, 0)) losssum
from stdw.f_t_lossdetail t
group by t.declaredetailpkno) loss_d
on detail.pkno = loss_d.declaredetailpkno
and loss_d.losssum > 0
left join (select claim.declaredetailpkno,
sum(nvl(claim.claimsumdetail, 0)) claimsum
from stdw.F_T_ClaimDetail claim
group by claim.declaredetailpkno) claim_d
on detail.pkno = claim_d.declaredetailpkno
and claim_d.claimsum > 0
left join (select declareDetailPkNo,
sum(nvl(indemnityRptDetail, 0)) indemnityRptDetail
from stdw.F_T_IndemnityDetail
group by declareDetailPkNo) indemnity_d
on detail.pkno = indemnity_d.declaredetailpkno
and indemnity_d.indemnityRptDetail > 0
left join (select declaredetailpkno,
sum(nvl(recoverySumDetail, 0)) recoverySumDetail
from stdw.F_T_RecoveryDetail
group by declaredetailpkno) recovery_d
on
detail.pkno = indemnity_d.declaredetailpkno
and recovery_d.recoverySumDetail > 0
where product.pkno not in (7, 8, 12, 14, 38) /*有出運*/
and (loss_d.losssum is not null or claim_d.claimsum is not null or
indemnity_d.indemnityRptDetail is not null or
recovery_d.recoverySumDetail is not null) /*剔除沒有報損等信息的數據*/
group by detail.commityear,
detail.commitmonth,
policy.corppkno,
product.prdtsubcatpkno,
product.pkno
?
執行后,發現半天沒出來數。而且這些表中,數據量最大的表f_t_declaredetail也就幾百萬條,在極致情況下,最多返回幾百萬行數據。查看了下執行計劃,發現執行計劃和預計的不一樣,而且預估的結果集相當大。執行計劃如下:
? ? 根據圖示,可以比較清楚的看到,表f_t_recoverydetail居然與其他的表做了內嵌循環關聯,不可思議啊,而且返回的結果集,遠超百萬數量級,比f_t_declaredetail的數量級還大。起初以為是統計信息出了問題,查看了各表的統計信息,發現沒有什么異常。
? ? 后來靜下來想了想,返回的結果集肯定不會超過f_t_declaredetail的數據量,正好與f_t_recoverydetail關聯時,數據量嗖地上去了,初步懷疑是關聯的問題。可以回頭看下sql代碼,粗字體表明的地方就是問題所在:確實是表之間關聯出了問題。
? ? 總結:有時候肉眼看不出來,就用執行計劃看吧,還是有很大幫助的。呵呵
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
