在写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优化-提防错误关联的更多相关文章

  1. sql 优化

    1.选择最有效率的表名顺序(只在基于规则的优化器中有效): oracle的解析器按照从右到左的顺序处理 from 子句中的表名,from子句中写在最后的表(基础表driving table)将被最先处 ...

  2. SQL 优化总结

    SQL 优化总结 (一)SQL Server 关键的内置表.视图 1. sysobjects         SELECT name as '函数名称',xtype as XType  FROM  s ...

  3. (转)SQL 优化原则

    一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用 系统提交实际应用后,随着数据库中数据的增加,系 ...

  4. 提高SQL查询效率(SQL优化)

    要提高SQL查询效率where语句条件的先后次序应如何写 http://blog.csdn.net/sforiz/article/details/5345359   我们要做到不但会写SQL,还要做到 ...

  5. SQL优化法则小记

    SQL优化技巧 1.选择最有效率的表名顺序(只在基于规则的优化器中有效): oracle的解析器按照从右到左的顺序处理 from 子句中的表名,from子句中写在最后的表(基础表 driving ta ...

  6. SQL优化(zhuan)

    转自:http://www.jfox.info/SQL-you-hua 数据库的优化问题 一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出S ...

  7. SQL 优化原则

    一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用 系统提交实际应用后,随着数据库中数据的增加,系 ...

  8. [SQL]SQL优化34条

    我们要做到不但会写SQL,还要做到写出性能优良的SQL,以下为笔者学习.摘录.并汇总部分资料与大家分享! () 选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE 的解析器按照从右到 ...

  9. sql优化点整理

    此文是我最早开始sql优化至今整理的小知识点和经常遇到的问题,弄懂这些对优化大型的sql会有不少帮助 ---------------------------------使用了多余的外连接------- ...

随机推荐

  1. 操作引入xml文件的书包(定位到指定节点)

    定位到指定节点:e0.1 <chtml><we>@{_samples/test.xml:HtokID=e0.1}</we></chtml> 上述表达式表 ...

  2. FxMaker用法

    第一步:选sceneFxMaker幕后,执行 第二步:执行界面,选中EffectParticle制作粒子特效 第三步:随便点中一个粒子特效.例如以下所看到的 第四步:点中右側的"Explos ...

  3. Winform - 全屏显示

    //全屏显示 this.WindowState = FormWindowState.Maximized;

  4. 基于visual Studio2013解决C语言竞赛题之1085相邻之和素数

        题目 解决代码及点评 /************************************************************************/ /* ...

  5. [置顶] 遇到难题(bug)的解决方法心得

    今天早上花了2个小时解决一个问题...界面抖动.. 最近把淄博项目的界面用BT改了,后来发现4个界面之间切换会抖动.. 就是整个界面会左右抖动... 文章出处: PHP攻城师 www.phpgcs.c ...

  6. PO经批准的订单API

    DECLARE l_return_status VARCHAR2(1); l_exception_msg VARCHAR2(4000); BEGIN mo_global.set_policy_cont ...

  7. Swift - 使用Auto Layout和Size Classes实现页面自适应弹性布局

    在过去只有iphone4的时候,可以在代码里将一个可视单元的位置写死,这样是没问题的,但随着iPhone5,6的发布,屏幕尺寸有了越来越多种可能.这就要求App的UI控件具有在不同屏幕尺寸的设备上具有 ...

  8. JSP的学习(8)——JSP标签

    JSP标签也称为JSP Action(JSP动作)元素,用于在JSP页面中封装Java代码,这样使得在JSP页面中避免直接编写Java代码,让JSP真正成为MVC模式中的作为视图作用. 几个JSP常用 ...

  9. 一种根据URL参数条件动态生成URL的方法

    最近做了一个产品列表页类似于搜索列表页, 功能比较简单,比搜索页复杂的逻辑在于,生成各个查询条件的URL.我们的链接如下: http://xxx.xxx.xxx/product/list.html?s ...

  10. Windows下用Mingw编译Boost.Regex库

    下载Boost库,解压. 定位到regex库文件夹下. GCC所对应的MAKEFILE为gcc.mak 进入命令提示符下,输入make -f gcc.mak 这是如果直接按回车执行的话,会出现错误: ...