OS:win7html
Cpu:8 核web
集算报表:1120 安装版sql
Jvm:1G数据库
数据库:oracle11goracle
有一个交叉汇总报表,其实格式很简单,行列各一个统计维度。但后台业务表的数据有 175 万条,且还要与其余表(大概在 7w 条左右)作 join,若是由 sql 来处理,能够想象到会慢到什么程度,关键受各类条件影响,可否查出数据都是问题。jvm
注:ACCORECEIVE 表 175w 条数据测试
目前,测试 birt 需 5 分钟,借助各类中间表与视图。报表友商没法出表。大数据
要求:能作出该报表在 web 展示,且重要的是速度要快,另外,数据(目前大概是 5 年数据)是实时增长的。ui
客户报表格式及目前所用 sql:spa
报表格式:
Sql:
select LOCATIONS.loupan loupan, LOCATIONS.LPORDERNUM, nvl(ACCORECEIVE.RECEIVABLEAMOUNT, 0) yingshou, chargeproct.Description CHARPNAME, chargeproct.ordernum chordernum from ACCORECEIVE,V\_LOCATION\_LP\_LG\_DY LOCATIONS,chargeproct where ACCORECEIVE.Org\_Id = LOCATIONS.Org\_Id and ACCORECEIVE.Sub\_Org\_Id = LOCATIONS.Sub\_Org\_Id and ACCORECEIVE.Fk_Locationid = LOCATIONS.Locationid and ACCORECEIVE.Fk_Chargeproctid = chargeproct.chargeproctid(+) and ACCORECEIVE.Wf_Status not in('做废')
select LOCATIONS.loupan loupan, LOCATIONS.LPORDERNUM, nvl(ACCORECEIVE.RECEIVABLEAMOUNT, 0) yingshou, chargeproct.Description CHARPNAME, chargeproct.ordernum chordernum from ACCORECEIVE,V\_LOCATION\_LP\_LG\_DY LOCATIONS,chargeproct where ACCORECEIVE.Org\_Id = LOCATIONS.Org\_Id and ACCORECEIVE.Sub\_Org\_Id = LOCATIONS.Sub\_Org\_Id and ACCORECEIVE.Fk_Locationid = LOCATIONS.Locationid and ACCORECEIVE.Fk_Chargeproctid = chargeproct.chargeproctid(+) and ACCORECEIVE.Wf_Status not in('做废')
常规模式下,大数据要出交叉报表几乎很难,这里受 sql 效率慢、jvm 等的影响,一次若是把全部数据所有取出则必然极大可能内存溢出。另外,大数据表再有 join,即使能取,那取数速度上确定也没法保证(sql join 的效率低),上面 sql 中能体现出全部问题。
解决方案:
一、为避免一次性取数内存溢出,可采用集算器游标 cursor 取数; –cursor
二、去除不须要字段及 join 字段。分析后发现,客户实际不须要 org_id、sub_org_id 的关联;
三、取数后可根据客户所出报表对应作数据处理,这里可 groups 处理一次分组汇总;–替代报表表达式 group
四、为摆脱 sql join 效率低问题,可将 join 放在集算器内处理,这里 ACCORECEIVE 与 V_LOCATION_LP_LG_DY 表(query 便可,数据不大)分开取数; –switch 链接
注:集算器中测试了两表 sql 中 join,时间大概需 5 分钟。
五、结合客户报表格式及所用的数据库表,可将上面 sql 中 chargeproct 表放到报表 sql 取数,因其仅体现显示值做用,且仅几十条数据。
集算脚本:
注:代码有每一步的做用说明
结论
–
润乾能出表且速度最快,客户联系人是很是满意的。对比:
一、友商:没法出表,包含不作 join 仅单查业务表数据。
二、Birt:客户说 四、5 分钟出表,虽没法验证,但我的有点怀疑;
三、润乾:12s(屡次测试)左右,(取数 + 报表展示)。–因数据处理在集算器已完成,因此报表几乎无计算,报表计算及生成 html(大概是 20 行 +35 列的单元格)基本不占用时间。