有时报表在展现或导出时需要从数据库中取出较多数据,而JDBC的取数速度一向比较慢,有可能超过报表其它运算环节的耗时,导致整个报表的生成过程效率极低。下面我们看如何利用润乾集算报表的并行计算机制提高JDBC的取数性能。
所谓并行取数是指,使用多线程技术在报表工具与数据库建立多个连接,同时读取一份源数据,这需要将源数据分段,每个线程(数据库连接)读取其中一段内容,最后将所有线程的结果合并得到总目标数据的过程。
集算报表内置了并行机制可以很容易完成并行取数任务,从而提升报表性能,这里以oracle为例说明实现过程。
报表描述
用户状态表展现的是明细数据,由于需要导出,必须一次性读取数据表中所有数据。单表数据量为360万,报表样式为:
编写脚本
使用集算器编写脚本(parallel.dfx),实现并行取数逻辑。首先确定分段字段,这里选择数值型的userid字段,再据设定的线程数和userid最大值(指定为大数值常量)计算每段中userid的范围;最后根据指定的数据范围通过sql分段读取数据,完成多线程取数过程。以下为实现脚本:
A5通fork使用多线程执行网格中的代码块,实现并行取数;
B6-B9完成并行取数,每个线程运行结果返回A8格;
A10为报表返回合并后的结果集。
编制报表
新建报表模板后,数据集选择“集算器”,在数据集编辑窗口指定上述编辑好的dfx文件,完成数据集创建。
设置报表模板表达式:
A2:根据数据集ds1使用select函数取用户登录信息列表;
A2-G2:根据A2扩展,通过取值表达式分别取用户ID、账户、在线等信息。
并行后效果
报表运行后记录数据集计算时间,分别比较并行前和并行后的运行结果:
上面看到了并行取数带来的效果,通过集算报表的并行机制可以加速取数过程,从而提升了整体报表性能,测试结果因测试环境而异,本机配置详见附录。
使用多线程并行取数适合数据库资源比较空闲(如连接数未达上线)的情况,通过这种方式充分利用数据库资源。如果数据库任务已经饱和,这种方法会进一步加重数据库负担,而不会起到提高速度的作用。
此外,分段字段的选择对性能影响较大。最好是选择递增插入的有索引字段,如作为主键的流水号,这样数据库能充分利用索引减少遍历范围;尽量选择数值类型的字段,作为条件的运算性能更高且易于拆分。实际操作中要综合考虑这两方面因素,本例中由于没有索引和主键,所以选择了数值型userid。实际业务中经常能找到递增插入的有索引数值型字段,采用并行取数的方式获得的性能提升也会更好。
【附】测试机配置
测试机型:Dell Inspiron 3420
CPU:Intel Core i5-3210M @2.50GHz *4
RAM:4G
HDD:西数WDC(500G 5400转/分)
操作系统:Win7(X64) SP1
JDK:1.6
数据库:oracle11g R2
集算报表版本:5.0