设为首页 收藏本站
查看: 890|回复: 0

[经验分享] oracle数据源的报表sql计算慢&解决

[复制链接]
YunVN网友  发表于 2016-8-16 07:35:47 |阅读模式
  问题描述
  项目里有些报表出来的速度特别慢,尽管对润乾报表和Oracle数据库做了很多优化,效果还是不理想,这些报表普遍数据量比较大,涉及到的数据库表多(几十张)、表间关联频繁(还有自连接),报表里也有多个汇总、比值等计算。
  以其中一个明细报表为例,它的SQL如下:
  (select *
  from (select syb.org_abbn as syb,
  max(xmb.org_abbn) as xmb,
  sub.org_subjection_id as sub_id,
  oi.org_abbn as org_abb,
  rm.rec_notice_org_id,
  rm.synergic_team as xz_team,
  xzdw.coding_name as xz_org,
  l.requisition_cd as req_cd,
  l.requisition_id as req_id,
  l.note as req_note,
  nvl(decode(l.ops_content6,
  2000200012,
  '否',
  2000200011,
  '是'),
  '') as sflj,
  --太长了,省略大部分select子句
  fromlcr l
  left join lcrrm on rm.requisition_id =
  l.master_bill_id
  andrm.table_type = '0'
  andnvl(rm.bsflag, 0) != 1
  
  left join cos sub on l.org_id = sub.org_id
  andnvl(sub.bsflag, 0) != 1
  left join coioi on oi.org_id = sub.org_id
  andnvl(oi.bsflag, 0) != 1
  --太长了,省略大部分jion
  wherel.table_type = '1'
  andl.requisition_state = '0101020304'
  andnvl(l.bsflag, 0) != 1
  andto_char(l.back_date, 'yyyy-MM-dd') between '2012-01-01' and
  '2012-04-25'
  group by l.requisition_id,
  l.note,
  l.requisition_type,
  sub.org_subjection_id,
  syb.org_abbreviation,
  rm.rec_notice_org_id,
  oi.org_abbreviation,
  --太长了,省略大部分group by 字段
  ) a--主查询a
  LEFT JOIN crviewve--视图ve
  ON ve.requisition_id = a.req_id
  
  这个sql里关联的表很多,嵌套多层子查询,最后又与一个视图进行关联(视图也很复杂)。该报表查询4个月的数据,计算时间为6分42秒,太慢了远远达不到用户要求。
  我们对这个报表做过几次优化,但sql复杂度较高,基本没有优化空间,而且由于是实时查询,所以无法采用事先计算建立中间表的方法。后对这个报表进行监控发现,数据集SQL执行需要5分钟,计算展现需要1分多钟,数据集SQL慢的原因是其中两个子查询(主查询a和视图ve)做join的效率极低。
  所以优化思路定为——优化数据集取数,改善SQL的join效率低的情况,顺便优化报表计算展现。
  解决过程
  我们是用集算器(报表厂家的东西)解决这个问题:
  1、拆分原报表数据集SQL
  分别把两个子查询sql写到集算器,并用switch完成关联(Switch是它的函数,比较新颖,能将外键指向的记录直接当成本记录的属性,也支持join,视不同情况使用)。
  2、消除报表格间运算
  将原报表模板中的比值和汇总值这些全部移到集算器中做,少了单元格遍历,报表计算速度也能提高。
  3、将结果集一次返回给报表
  完成所有数据准备后,把计算结果一次性返回给报表工具,报表接收到数据源后直接进行展现(不再做其他如格间计算类的影响效率的计算)。
  
  总体代码如下:
DSC0000.png
 
  解决效果
  该报表展现时间从原来的6分42秒锐降到57秒,优化效果非常明显,超出了用户预期。其他有类似问题的报表也准备采用这个思路。
  问题小结
  主查询a和视图ve分别在Oracle跑时只需要10到40秒,但二者做jion却需要好几分钟,原因在于Oracle在完全自动制定查询计划的时候,并不是每次都能找到合理的方法(人工干预比较费劲)。集算器能提升性能是因为ve是a的维表,可以用特别的switch方法。由人来决定复杂查询的路径,结合Oracle的基础查询语句,速度就显著提升了。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-258521-1-1.html 上篇帖子: Oracle 用户表空间的创建和授权 下篇帖子: Oracle--查看和修改数据库字符集编码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表