在选择报表工具时,性能一直是用户关心的指标,但是,报表工具的性能和整个报表系统的性能有多大关系呢?
要回答这个问题,首先要分析一下报表的处理过程包含哪些环节,哪些环节容易出现性能瓶颈,如何优化这些环节。
一、报表处理的一般过程分析
1、用户选择报表输入参数后,报表引擎会根据报表模板和输入参数来解析报表,并将数据计算和读取请求以SQL的方式发送给数据库。
2、数据层负责读取、计算和返回数据。数据层一般都是传统关系数据库:如Oracle、DB2等。
3、数据层通过JDBC等接口将结果数据传输给报表工具。
4、报表工具利用自身的计算能力,对数据进行再次计算。
5、报表工具将计算好的数据,按照报表模板的样式生成可视化页面展现给用户。
二、报表工具与报表性能的关系
理论上说,上述这些处理过程,网络、报表层和数据层的各个环节都有可能成为性能的瓶颈。我们将针对几个影响报表性能的环节逐个分析,看看决定这些环节性能的主要因素,以及这些因素与报表工具的关系。
1. 数据库计算数据环节。
在实际项目中,数据库的数据经常需要经过一系列计算才能在报表上显示出来。开发人员一般是编写一些很长很复杂的SQL语句(或存储过程)做数据准备。因此,这个环节主要是数据库来计算,其性能与报表工具没有什么关系。
在这个环节中,报表工具对整个报表系统的性能没有什么影响,主要影响因素是数据库对数据源的计算,这也是报表系统性能的优化重点。
开发人员会发现,使用SQL(或存储过程)实现复杂统计运算非常困难,性能也不容易优化。特别是与序和集合有关的运算,如计算每月销售额都排进前10名的产品、连续五天上涨的股票等。为报表准备数据的SQL过于复杂,可能长达数十行甚至数百行。
例如,计算每个月的销售额都在前10名的客户,用SQL实现如下:
select Client from(
select * from(
selectB.*,row_number() over(partition by month order by SumValue desc)
rown from(
selectto_char(SellDate,'mm') month,Client,
sum(Quantity*Amount) SumValue
from contract
whereSellDate>=to_date('2012-01-01','yyyy-mm-dd')
andSellDate<=to_date('2012-12-31','yyyy-mm-dd')
group byto_char(SellDate,'mm'),Client order by month,client
) B
)C
where rown<=10
)D
group by Client
having count(Client)=(
select count(distinct(to_char(SellDate,'mm')))
from contract
whereSellDate>=to_date('2012-01-01','yyyy-mm-dd')
andSellDate<=to_date('2012-12-31','yyyy-mm-dd')
)
因为难以完整指定数据库的执行路径,所以复杂SQL执行起来一般都比较慢,想优化这些复杂SQL也很难入手。因此,在数据计算环节影响报表性能的主要因素是数据库和SQL。
2. 数据库JDBC传输环节
传统主流数据库提供的JDBC驱动在将数据流转换成Java对象时的效率很低,但又不可避免,大数据量情况下速度非常慢。虽然数据库的版本一直在升级,但是这个问题一直都没有解决好。
所以,对于较大源数据量报表来说,JDBC也是报表变慢的主要因素。因为主流数据库的JDBC是由数据库厂家提供的,所以,这方面的性能和报表工具也没有太大关系。
3. 报表工具计算数据环节
在大多数并发不大的情况下,传输给报表工具端的数据量很少,报表工具也不会承担较复杂的数据计算,即使报表工具本身性能较差也不会有很明显的感觉。但是,也有少数的情况下,报表开发人员会把数据计算放到报表工具里执行。报表工具要承担较大的计算量,可能会成为报表性能的瓶颈。这时,不必急于考虑采用更高性能的报表工具,可以详细分析一下开发人员在报表工具中计算的原因。
开发人员这样做的原因之一,是报表的计算较为复杂,使用SQL实现会非常困难。这时,程序员就会采用报表工具提供的直观计算方式来完成报表中的计算,比如:润乾报表的格间计算或者BIRT的多结果集关联等。这样做会导致报表工具要完成较大量的数据计算。而报表工具大都采用内存计算方式,并在单元格计算过程中是带有呈现属性的,这样不仅性能低下,而且很容易造成内存溢出。
4.并发访问的性能
当报表并发访问量较大的时候,即使单个报表运算量不大,但并发多也就会造成明显的等待感。这时候报表工具的计算性能就和报表整体性能相关性较强,选择计算性能较好的报表工具可以提升整个报表系统的性能。
但是,具备高性能计算能力的报表工具并不能解决内存占用较多的性能问题。有的时候,为了实现较复杂的计算,报表工具不得不占用更多的内存。例如:报表工具为了实现复杂计算,可能会把中间结果放到报表的隐藏行、隐藏列中,实际上增加了报表工具对内存的占用。
对于Java报表工具而言,JVM会使用操作系统的虚拟内存或者交换区,发生内外存交换。内外存交换实际上是对硬盘的读写,再加上频繁的垃圾回收动作,其消耗的时间甚至要远远超过计算本身的时间。这时,在同等并发情况下,选择占用内存更少的报表工具比计算更快的报表工具对性能优化更有意义。