birt遇到一个大报表,涉及四张数据库表(一个交易流水表和三个维表,维表通过主键和流水表关联,流水表比较大数据量超过35G),数据量1亿条/40G,带有若干过滤条件,在oracle里跑,查询300多秒,报表展现超过400秒。报表sql长这个样子:select… from A,B,C,D whereA.k1=B.k1 and A.k2=C.k2 and C.k3=D.k3 and A.a3 like ’209474%’计算慢主要是因为数据量太大,过滤效率低。

这个报表属于T+1类(晚上算第二天看)的报表,现在的计算速度客户勉强能够接受,但考虑到数据增长速度,好日子持续不了多长时间,所以着手进行优化,但Oralcesql搞过几轮后效果依然不理想。

前几天转过一篇文章,也是解决报表慢的(戳这里),让销售想了点办法找到厂家(拓宽一下解决问题的思路嘛),搭了个环境测试了一下,写个备忘。

基本思路是把数据从数据库导到文件里,把三个维表读入内存,在多台PC中利用并行计算与流水表分段连接。

数据从oracle进到文件系统中,用列式二进制方式存储,把多列甚至每一列存成一个文件,报表计算的时候只需要读入相关列,节省了数据库的读写时间。行式数据转列式文件的脚本如下:

094546583.png

报表计算

主程序进行任务拆分,指定4台机器执行16个并行任务:

094549332.png

子程序1维表进行关联,将关联后的结果存入全局变量中,供该机器上其他并行程序(多个)调用,避免每个子程序装载一次维表出现内存溢出的情况。

094552966.png


子程序2全局变量(维表)和流水表(事实表)进行连接、数据过滤,最后将结果返回给主程序。

094555998.png


并行计算结果归并后,会以二维表的方式作为数据集返回给BIRT


利用集算器的并行计算为报表提供数据源的方式,报表展现从原来的400(近7分钟)缩短到了1803分钟),速度提升了1倍还多,效果明显。


用户环境:IBM 75016cpu*4cRAM 128GOracel1gEMC存储;

测试环境:4 PCsCPU IntelCore i5 2500RAM 16GHDD 2T/7200rpmLAN 1000M。如果进一步增加PC数量,或者用更高配置的PC,估计计算速度还会进一步提高。


http://esproc.blog.51cto.com/8028595/1341392