sql优化-提防错误关联

系统 1835 0

    在写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代码,粗字体表明的地方就是问题所在:确实是表之间关联出了问题。

    总结:有时候肉眼看不出来,就用执行计划看吧,还是有很大帮助的。呵呵


 

 

sql优化-提防错误关联


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论