
报表软件FineReport报表性能优化(3).pdf
5页报表软件 FineReport 报表 性能优化 (3) 启用行引擎执行层式报表 1. 问题描述 这样一种报表:报表形式非常简单,只是简单的单数据源明细报表,但是数据量非常大,百万、千万甚至更多报表取数及计算时间相当长 希望能够提高报表展示速度,对于用户来说,查询报表不会有滞后的感觉 2. 解决方案 2.1 解决方案 对于 单数据源明细报表 ,可以启用 行引擎来执行报表 ,提高报表展示速度,优化用户体验 2.2 原理 普通报表 :取出全部数据后再执行报表,最后返回整体的报表结果给浏览器,用户访问到看到结果的时间 =报表取数时间 +报表执行时间; 行引擎报表 :边取数边执行报表,执行到哪页用户就可以看到哪页,用户访问到看到结果的时间 =首页数据读取时间 +首页计算时间 2.3 注意事项 行引擎报表注重的是性能,由原理我们可以想象,对于行引擎报表,每页的计算必须是独立的,即报表不能有单元格关联的复杂运算,类似,为了提高行引擎报表的性能, FR 舍弃了一些复杂的功能: 行引擎报表只适用于单数据源、即单元格过滤不能使用,且必须是简单明细表,同时也不支持 计算、条件属性等复杂报表功能。
3. 实现步骤 我们以 mysql 数据库为例,将里面的 S 订单明细 的数据用行式引擎显示,每页显示 30行,设置如下: 3.1 新建数据集 数据集 ds1: SELECT * FROM S 订单明细 3.2 模板主体设计 如下图,将表中的列全部拖曳至模板主体中: 3.3 行式引擎设置 选择 模板 >报表引擎属性 ,勾选 用行式的引擎来执行报表 ,再勾选下面的 使用按页运算分段执行报表 ,每页记录数使用默认值 30,如下图: 3.4 效果查看 点击分页预览,效果如下: 行式引擎按页取数只适用于 Oracle,mysql,hsql和 sqlserver2008及以上数据库,其他数据库,如 access, sqlserver2005等必须手动编写分页 sql,才能实现按页取数,对于需要编写分页 sql的数据库,请参考 单数据源实现层式报表 章节 行式引擎只适用于单数据源报表,对于多数据集报表,行式引擎无法实现对其进行分页显示,多数据源的层式报表的实现请查看 多数据集实现层式报表 单数据集分页 SQL 实现层式报表 1. 问题描述 行式引擎按页取数只适用于 Oracle,mysql,hsql和 sqlserver2008及以上数据库,其他数据库,如 access, sqlserver2005, sqlite等必须编写分页 SQL。
上一节 介绍了直接行式的引擎实现层式报表的做法,下面以 Access 数据库为例介绍需要写分页 SQL的数据库怎样利用行式的引擎实现层式报表 2. 解决思路 对于 mysql这类可以直接使用行式的引擎实现层式报表的数据库来说,如果勾选了行式引擎,程序会自动生成分页 sql,如,我新建了一个数据集 ds1,来源于 mysql 数据库,基本 sql语句为: SELECT * FROM 订单明细 如果不定义分页 sql,勾选行式引擎选项,预览报表时,程序会将上面的 sql 语句转化为下 面的语句来取一页的数据: SELECT COUNT(*) AS totalRowCount FROM (SELECT * FROM 订单明细 ) t 如果数据库是上面所说的 access 一类的无法直接生成分页 sql 的数据库,那么就需要编写分页 SQL 3. 操作步骤 以 FRDemo内置的 sqlite为例,说明 sqlite如何写分页查询 3.1 新建数据集 新建数据集 ds1: SELECT * FROM 订单明细 3.2 添加分页查询 SQL 语句 在数据查询面板中点击 分页查询 按钮,编辑分页 SQL 语句,如下图: 完整的 sql语句如下: 1. SELECT * 2. FROM ( 3. SELECT * 4. FROM( 5. SELECT * 6. FROM 订单明细 ORDER BY 订单ID ASC limit ${fr_pagesize*fr_pagenumber} 7. ) AS e1 ORDER BY 订单 ID DESC limit ${ 8. if(fr_pagenumber == int((((fr_rowcount-1)/fr_pagesize)+1)),fr_rowcount - (fr_pagesize*(fr_pagenumber-1)),fr_pagesize) 9. } 10. ) AS e2 ORDER BY 订单 ID ASC SELECT * FROM ( SELECT * FROM( SELECT * FROM 订 单注:上述代码放置在分页 sql面板中时,要删除后 面的注释语句,并且语句中的三次 ORDER BY 一定不能丢。
分页 sql 语句注释 ${if(fr_pagenumber ==int( (((fr_rowcount-1)/fr_pagesize)+1)),fr_rowcount - (fr_pagesize*(fr_pagenumber-1)),fr_pagesize)}意思是: 假如是最后一页的话,就取最后一页剩余的行数,假如不是最后一页就取每页需要显示的行数,示例中每页需要显示的行数为 30 行 fr_pagenumber:当前浏览的页数,如果预览第 2页,则 fr_pagenumber=2; fr_rowcount:当前数据集的总数据条数; fr_pagesize:表示设置行式引擎时,每页需显示的行数,该示例中 fr_pagesize=30. 在预览时,设定的分页查询根据 3个变量的值,会生成数据库查询,如 fr_pagenumber=2,fr_pagesize=30时,即在 web端预览报表,预览至第 2页时,上面的 sql语句会转化为: SELECT * FROM ( SELECT * FROM ( SELECT * FROM 订单明 细 ORDER BY 订单 ID ASC limit 60 )AS e1 ORDER BY 订单 ID DESC limit30 ) AS e2 ORDER BY 订单 ID ASC 预览至第 3页时, fr_pagenumber=3, sql语句就转化为: SELECT * FROM ( SELECT * FROM ( SELECT * FROM 订单明细 ORDER BY 订单 ID ASC limit 90 )AS e1 ORDER BY 订单 ID DESC limit30) AS e2 ORDER BY 订单 ID ASC 预览至最后一页时,所剩下的数据可能不足 30 行,那么 sql语句又会转化成什么样呢? 如果 fr_rowcount=100, fr_pagesize=30,即数据总行数为 100行,每页显示 30 行,预览至最后一页,也就是第 4页时, fr_pagenumber=4, sql语句将转换为: SELECT * FROM ( SELECT * FROM ( SELECT * FROM 订单明细 ORDER BY 订单 ID ASC limit 90)AS e1 ORDER BY 订单 ID DESC limit10 ) AS e2 ORDER BY 订单 ID ASC 3.3 报表主体设计 将数据集中的数据列拖曳至单元格中。
3.4 行式引擎设置 同 上一节 的设置方法,这里不再赘述 3.5 效果查看 点击分页预览,效果图如下: 已 完 成 模 板 请 参照: %FR_HOME%\WebReport\WEB-INF\reportlets\doc\Advanced\PagingSql.cpt 查看模板效果请点击 PagingSql.cpt 4. ACCESS 数据库的分页 SQL 语句 1. SELECT * 2. FROM ( 3. SELECT TOP ${ 4. if(fr_pagenumber == int((((fr_rowcount-1)/fr_pagesize)+1)),fr_rowcount - (fr_pagesize*(fr_pagenumber-1)),fr_pagesize) 5. } * 6. FROM( 7. SELECT TOP ${fr_pagesize*fr_pagenumber} * 8. FROM 订单明细 ORDER BY 订单 ID ASC 9. ) AS e1 ORDER BY 订单 ID DESC 10. ) AS e2 ORDER BY 订单 ID ASC SELECT * FROM ( SELECT TOP ${ if(fr_} * FROM( 注: sqlserver2005和 access数据库操作步骤一样。
