报表工具与报表性能的关系

        在选择报表工具时,性能指标一向是用户非常关心的,但是,报表工具的性能和整个报表系统的性能会有多大关系呢?

        要回答这个问题,首先要分析一下报表的处理过程包含哪些环节,其中有哪些环节容易出现性能问题,如何优化这些环节。

        一、报表处理的一般过程分析

        1、用户选择报表输入参数后,报表引擎会根据报表模板和输入参数来解析报表,并将数据计算和读取请求以SQL的方式发送给数据库。

        2、数据层负责读取、计算和返回数据。数据层一般都是传统关系数据库:如Oracle、DB2等。

        3、数据层通过JDBC等接口将结果数据传输给报表工具。

        4、报表工具利用自身的计算能力,对数据进行再次计算。

        5、报表工具将计算好的数据,按照报表模板的样式生成可视化页面展现给用户。

        二、报表工具与报表性能的关系

        理论上说,上述这些处理过程,网络、报表层和数据层的各个环节都有可能成为性能的瓶颈。我们将针对几个影响报表性能的环节逐个分析,看看决定这些环节性能的主要因素,以及这些因素与报表工具的关系。

        1. 数据库计算数据环节。

        在实际项目中,数据库的数据经常需要经过一系列计算才能在报表上显示出来。报表开发人员一般是编写一些很长很复杂的SQL语句(或存储过程)来为报表计算数据。因此,这个环节主要是数据库来计算,其性能与报表工具没有什么关系。

        在这个环节中,报表工具对整个报表系统的性能高低没有什么影响,主要影响因素是数据库对数据源的计算,这也是报表系统性能的优化重点。

        开发人员会发现,使用SQL(或存储过程)实现复杂统计运算非常困难,性能也不容易优化。特别是与序和集合有关的运算,如计算每月销售额都排进前10名的产品、连续五天上涨的股票等。为报表准备数据的SQL过于复杂,可能长达数十行甚至数百行。

        例如,计算每个月的销售额都在前10名的客户,用SQL实现如下:

                select Client from(

                select * from(

                select B.*,row_number() over(partition by month order bySumValuedesc)

                rown from(

                select to_char(SellDate,'mm') month,Client,

                sum(Quantity*Amount) SumValue

                from contract

                where SellDate>=to_date('2012-01-01','yyyy-mm-dd')

                and SellDate<=to_date('2012-12-31','yyyy-mm-dd')

                group by to_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

                where SellDate>=to_date('2012-01-01','yyyy-mm-dd')

                and SellDate<=to_date('2012-12-31','yyyy-mm-dd')

                )

        因为难以完整指定数据库的执行路径,所以复杂SQL执行起来一般都比较慢。报表开发人员想人工优化这些复杂SQL的时候也会发现很难入手。可以看到,“数据计算”环节影响报表性能的主要因素是数据库和SQL,而不是报表工具。

        2. 数据库JDBC传输环节。

        传统主流数据库提供的JDBC驱动在将数据流转换成Java对象时的效率很低,但又不可避开,在大量数据时就会感觉速度非常慢。虽然数据库的版本不断升级,但是这个问题一直都没有解决好。

        所以,对于较大源数据量报表来说,JDBC经常也是报表变慢的主要因素。因为主流数据库的JDBC是由数据库厂家提供的,所以,这方面的性能和报表工具也没有太大关系。

        3.报表工具计算数据环节。

        在大多数并发不大的情况下,传输给报表工具端的数据量很少,报表工具也不会承担较复杂的数据计算,即使报表工具本身的性能较差也不会有很明显的感觉。但是,也有少数的情况下,报表开发人员会把数据计算放到报表工具里执行。报表工具要承担较大的计算量,可能会成为报表性能的瓶颈。这时,不必急于考虑采用更高性能的报表工具,可以详细分析一下开发人员在报表工具中计算的原因。

        开发人员这样做的原因之一,是报表的计算较为复杂,使用SQL实现会非常困难。这时,程序员就会采用报表工具提供的直观计算方式来完成报表中的计算,比如:润乾报表的格间计算或者BIRT的多结果集关联等。这样做会导致报表工具要完成较大量的数据计算。而报表工具大都采用内存计算方式,并在单元格计算过程中是带有呈现属性的,这样不仅性能低下,而且很容易造成内存溢出。

        4. 并发访问的性能。

        当报表并发访问量较大的时候,即使单个报表运算量不大,但并发多也就会造成明显的等待感。这时候报表工具的计算性能就和报表整体性能相关性较强,选择计算性能较好的报表工具可以提升整个报表系统的性能。

        但是,具备高性能计算能力的报表工具并不能解决内存占用较多的性能问题。有的时候,为了实现较复杂的计算,报表工具不得不占用更多的内存。例如:报表工具为了实现复杂计算,可能会把中间结果放到报表的隐藏行、隐藏列中,实际上增加了报表工具对内存的占用。

        对于Java报表工具而言,JVM会使用操作系统的虚拟内存或者交换区,发生内外存交换。内外存交换实际上是对硬盘的读写,再加上频繁的垃圾回收动作,其消耗的时间甚至要远远超过计算本身的时间。这时,在同等并发情况下,选择占用内存更少的报表工具比计算更快的报表工具对性能优化更有意义。

        三、优化报表性能的新选择

        经过上面的分析,我们发现,在大多数情况下,整个报表的性能和报表工具的展现部分关系并不大,最主要的影响因素是数据源计算和传输(从经验上看能占到80%)。如果想提高报表的性能,应当更多地在数据源计算上做文章,选择这方面能力较强的报表工具。

        可以考虑采用润乾公司新出品的集算报表5.0,集算报表中内置了数据计算语言集算器(esProc),能够更好的优化报表系统,提高性能。

        1. 用集算报表来优化数据库计算数据环节性能。

        针对复杂SQL很难优化的问题,集算报表内置了集算器(esProc)这种过程化的编程语言,其代码更符合自然思维习惯,解决同样问题会比SQL短数倍。一方面,易于开发、调试和维护,降低了开发成本;另一方面,由程序员决定计算执行过程和路径,更易于提高计算性能。

同样是上面的例子,计算每个月的销售额都在前10名的客户,用集算器实现如下:


        集算报表可以无缝接收A7的返回结果,不需要复杂计算,直接展现。

        2. 用集算报表来优化数据库JDBC传输环节性能。

        如果报表通过JDBC访问数据库出现传输缓慢的问题,可以考虑将较大规模的历史数据存在文件系统中。集算报表可以利用集算器来访问文件系统中的数据,要比传统数据库的JDBC数据传输的速度快很多。虽然集算器对集算报表提供数据也是JDBC方式,但集算器JDBC不需要再做数据流的对象转换,要比传统数据库快很多。

由于集算报表的计算和展现是分开的,所以可以利用集算器并行机制,同时用多个子程序通过不同的JDBC连接同时从数据库中取数。实际对oracle数据库的测试发现,16个并行任务同时取数的时候,速度可以提高十倍。但是,考虑到数据库压力增加的问题,这个解决办法仅适用于数据库本身负载压力较小的情况。

        3. 用集算报表来优化报表计算数据环节性能。

        针对报表内的计算环节,可以考虑用集算报表内置的集算器这种过程化的开发语言代替。集算器在降低数据计算编程的难度的同时,可以将数据计算和报表展现分开,提高报表性能。对于这个环节,集算报表(集算器)的优点在于:

        1)集算器不附带显示属性,有效提高计算速度。

        2)集算器具有关系数据计算的完备、丰富的类库,提供了大量提高性能的优化选项。特别是与序和集合有关的运算,程序员可以有效利用数据在业务上的规律,控制执行路径,提高计算速度。

        4.用集算报表优化报表大并发访问性能。

        使用集算报表后,可以把一些耗用内存较大的计算交给内置集算器这样的计算中间件去做。那么集算报表从集算器得到的结果中就不会包含中间数据了,也就不需要使用隐藏格。当并发量非常大的时候,集算报表去掉大量隐藏格会减少甚至避免JVM内外存交换,明显地提升报表的性能。

        值得一提的是,集算报表采用纯Java开发,非常容易集成到J2EE应用中。

阅读更多
个人分类: 胡说八道
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭