FineReport 性能优化
性能优化之三个疑问
疑问 1:为何要性能优化
您是否遇到访问一张报表时加载时间很长?
您是否遇到过频繁访问大数据量报表占用了过多的服务器内存而导致内存溢出?
您是否遇到过过多的用户并发访问的时候服务器承受压力过大导致服务器崩溃?
您是否遇到过访问了一张复杂报表,几分钟之后再次访问,又要等待很久?
您是否因为频繁地出现请求超时而恼火?
您是否…
疑问 2:影响性能的因素
疑问 1 的种种性能缺陷是如何产生的呢?一般有如下几方面存在性能问题:
报表取数
一般来说,报表越复杂,所涉及到的后台数据库基础表也就越多。除了格式简单的列表式报表需要在报表中显示超大的数据量外,大部分的报表是从几十万或者几百万的源数据中筛选,运算,返回几十条或几百条不等的数据结果。如果取数使用的方法不恰当,报表取数时间就会过长,从而影响性能
报表制作
报表制作时往往会使用字段的关联、高亮、数据字典、公式计算等等报表内置的功能,如果这些功能使用的不正确,或者报表存在 多余的设置,这样就会因为这些不必要的设置而增加计算时间,从而影响性能。
服务器性能
FineReport作为纯JAVA软件,可以与J2EE的应用无缝集成,集成至服务器的报表就会继承服务器的资源。服务器的虚拟内存、连接池的设置等等往往会导致很多性能问题。
疑问 3:如何优化性能
针对影响性能的因素,FineReport 有不同的优化方案。如:
· 对 SQL 的优化,使用存储过程等优化取数过程
· 减少冗余单元格及不必要的设置从而加快报表计算时间
· 采用并发设置,缓存设置,集群等提高服务器性能等等
简而言之,FineReport 性能优化,主要包括两个方面:
报表性能优化
服务器性能优化
性能优化之报表优化
一. 影响页面速度的几个重要因素
1.excel页面导入中增加了控件(增加控件的200行10列,页面加载约需要100秒左右,而去掉控件只需10秒左右)
2.数据集建立时使用select * ( 查询是只取自己需要的字段,会有20%-30%的效率影响)
3.数据库不建立索引或索引不合理(测试发现,excel导入10w条数据,建立索引和不建立索引,有大约5倍的性能差)
4.过多使用"过滤"操作(建立数据集时,使用where条件过滤,报表的效率会极大提高)
5.重复使用条件属性(针对行或列进行设置的条件属性,不需要正行整列均添加上,只要在任意一个单元格添加就好)
6.同一个页面控件数量太多(当一个页面的控件数量超过100个,就会拖慢页面展现速度,超过500就很容易造成超时)
7.过度依赖帆软来处理数据(非必要的各项运算,统计数量、过滤等等操作都交给帆软来做的时候,会发现效率远远低于数据库执行而直接返回结果)
二. 数据缓存与共享和缓存路径
1. 缓存至内存(默认)
设置方法:默认的就是使用内存缓存即所有数据都保存在内存中,在数据库查询窗口可以看到
设置后的效果:当执行数据集时就会在将此记过缓存至内存中,下次在执行此数据集时,会直接从内存缓存中取数.
优缺点:空间资源有限,但效率很高,取数速度快。
2. 缓存至磁盘
(即将数据缓存到服务器的磁盘中,默认是在C:\Users\用户名\.FineReport80\cache下)
设置方法:点击下拉框选择缓存至磁盘当记录数大于,并设置行数。
设置后的效果:记录数默认大于0行:表示从第0条数据开始,取出的数据是全部放在磁盘中。记录数大于如1000行:表示取得的数据前1000条是放入内存中,剩余部分缓存至磁盘,当用到1000条以外的数据时,就会从磁盘中读取数据。
优缺点:空间资源又大又便宜,几乎没有限制;但效率低,取数速度往往很慢。
3. 修改缓存路径
通过修改%FR_HOME%\WebReport\WEB-INF\resources\目录下的cache.xml文件(报表管理平台中设置缓存,提交后会生成该文件,如果没有则新建),给Basic标签增加cacheDirectory属性,如将缓存文件保存在D:\Cache目录下
三. 优化报表计算时间
3.1 空白单元格应用
报表中,只要一个单元格里有设置就会占用一份内存,而空白的单元格几乎是不占任何内存的。报表中由于布局的需要,不可避免地会出现一些只起到占位作用而无需其他的设置的单元格;尽量将这些单元格设成空白单元格,这样能够有效的减少内存的占用,加快报表的运算速度。
3.2 慎用隐藏行列
报表中为了进行一些复杂的运算,往往需用到隐藏行列来处理中间的运算,而这些隐藏行列中被用到的单元格,往往只有一两个格子,此时被隐藏行列中没被用到的单元格里有设置的话会额外浪费内存,因此建议把没用的单元格设为空白单元格,减少内存的占用,加快报表的运算速度。
3.3 慎用合并单元格
报表中,常常会用到合并单元格,合并单元格的所有属性都是保存在左上角的格子中的,而合并区域中的其他被合并的单元格,并不保存任何属性也不占用内存。虽然合并单元格的应用能够减少内存,不过因合并单元格的运算涉及到多个单元间的主被动关系,所以运算比较复杂,反而会降低运算速度。因此,我们建议慎用合并单元格,尽量将没用的单元格设成空白单元格。
3.4 相同效果的条件属性
同一行(列)中的单元格需要设置相同效果的条件属性时,只需在该行(列)中的某个单元格设置一下条件属性便可,这样能够加快报表的运算速度。如下图,需要隐藏某行时只需要在一个单元格中设置条件属性即可,不要每个单元格都设置。
3.5 相同效果的数据列基本属性设置
数据显示全列表格式比主列为列表格式,其他扩展列为分组格式要快。因为数据列设为分组时,报表会将取出的数据进行一次分组聚集的计算,而不管数据有没有重复。因此,对于可实现相同效果的应优先设置其数据列属性为列表。
3.6 父格设置
设置方式一:销量父格为产品名称
,产品名称父格为产品类型,产品类型父格为销售员、销售员父格为地区,父子格层次树为 4 层。
设置方式二:销量、产品名称、产品类型、销售员的父格都为地区,父子格层次为 1 层
上面两种设计方式的数据展示结果是一样的,不过报表的计算速度却不一样;第二种方式的报表计算速度明显会比第一种快。
3.7 取消自动调整行高或列宽
若已设置自动调整列宽的话,那么在报表展示前会先去计算单元格中数据的宽度或高度,这样就增加了报表的运算时间,所以尽量取消自动调整行高或列宽。选中单元格,在右侧列表中选择单元格属性表-其他属性,自动调整设置为否
3.8 优化过滤条件
查看模板中是否重复设置了过滤条件,删除多余的过滤条件,即若数据列来自相同的数据集,只需在最左父格设置过滤条件并勾选将父格子作为过滤条件(默认是勾选的)即可
四. 优化报表取数
4.1 取数原理
设计器拼出最终的SQL,将SQL语句传给数据库,数据库执行,将数据返回给设计器。
由于计算过程首先要通过SQL语句从数据库中取数据,我们可以通过控制数据量的大小和对数据的提前预处理来提高报表的性能
4.2 优化 sql
SQL语句取具体的字段
SQL中直接分组代替报表中分组
SQL中直接排序代替报表中排序
SQL中直接过滤代替报表中过滤
4.3 使用视图、存储过程
视图是由select语句组成的查询定义的虚拟表,由一张或多张数据库实际的表中的数据组成的,从数据库系统外部来看,视图就如同一张表一样。存储过程通过流控制与SQL语句,可以对数据进行强大的运算与处理,对于业务比较复杂的应用,常常需要将原始数据通过存储过程处理后再供报表使用。另外存储过程运行前,数据库会对其进行语法和句法的分析,并进行优化,这种已经编译好的存储过程极大地改善SQL语句的性能。在报表端也只需要书写较短的调用语句来获得结果,从而降低网络的通信量。所以表与表的连接、复杂的SQL尽量在数据库中使用视图或者存储过程直接进行,这样将复杂的SQL语句直接保存于数据库服务器端(数据库本身会对SQL语句进行语法分析并进行优化),在报表设计器端就不需要写大段的SQL语句而是直接调用视图或存储过程了,一方面减少网络传输量,减轻数据库的压力,另一方面加快了报表的运算速度。
性能优化之服务器优化
1. 内存
FineReport 内存机制
详见附件
FineReport 中的手动 GC 方法
详见附件
2. 并发数
报表并发控制
详见附件
模板结果缓存与共享
详见附件