有些报表查询出的数据行数可达千万甚至上亿,这类报表通常被叫做大报表,大多数情况下都是些清单明细数据报表,也有少量分组报表。
针对大报表,如果像常规报表一样,将数据一次性全取再交给前端呈现是不可行的。一是等待时间太长,用户体验差;二是很可能导致内存溢出造成应用崩溃。
那么,目前的报表产品是如何解决这一问题的呢?本文将调研并测试几款报表产品的大报表解决方案,还是针对这三款产品:润乾报表、帆软报表、Smartbi,均为最新版本。
首先了解下各家的解决方式或机制。
解决机制
帆软
帆软提供两种引擎,行式引擎专门解决明细大报表,新计算引擎可解决行式引擎及其不支持的一些情况(如某些数据库需手写分页 SQL 的问题、分组大报表、带汇总的分组报表等)。
行式引擎
实现原理是借助分页 SQL 按页取数,访问哪一页数据则取对应数据计算并呈现,所以也只能支持数据库源了。并且只有少部分数据库可以不改动 SQL 的情况下支持分页取数: Oracle,MySQL,HSQL 和 SQL Server 2012 及以上数据库。像其他的 access、SQL Server 2005 及 2008 等,必须手动编写分页 SQL 才能实现按页取数。可以看个例子感觉难易度:
原始 SQL:select * from 订单明细
SQL Server 2008 下的分页 SQL 为:
SELECT * FROM ( SELECT TOP ${ if(fr_pagenumber == int((((fr_rowcount-1)/fr_pagesize)+1)),fr_rowcount - (fr_pagesize*(fr_pagenumber-1)),fr_pagesize) } * FROM( SELECT TOP ${fr_pagesize*fr_pagenumber} * FROM 订单明细 ORDER BY 订单ID ASC ) AS e1 ORDER BY 订单ID DESC ) AS e2 ORDER BY 订单ID ASC
注:不同的数据库,写法不同。
新计算引擎
新计算引擎可以替代行式引擎的功能,使得做报表变的简单,比如对于 SQL Server 较低版本,不用再单独写分页 SQL,新计算引擎会把原本 SQL 处理成分页 SQL。但是原理不完全一样,行式引擎是按页取数(页面大小或页行数),新计算引擎则是每次按 1024 条(不支持自定义)为一个区间分批取数。
报表格式上也能支持分组大报表、带汇总的分组表。
帆软这两个引擎都是借助数据库分页机制,仅支持 SQL 数据源。新计算引擎的优势在于可以让定义 SQL 时更简单,如上面所提到的明细大报表按页取数手写分页 SQL 的问题,新引擎不用自己搞了。
使用数据库分页有几个共同的缺点:1、频繁反复翻页时效率很差,特别是靠后的页,对数据库造成很大压力;2、可能出现数据不一致(两次执行取数 SQL 之间有插入、删除动作);3、不支持其他类型数据源。
Smartbi
Smartbi 只能借助数据库 SQL 分页,因此仅支持 SQL 数据源,且报表格式仅支持明细报表,该机制缺点同帆软。
润乾
两阶段双异步线程
可参考下图
以 SQL 数据源为例,取数和呈现采用两个异步线程,取数线程发出 SQL 后,游标方式不断取出数据缓存到本地磁盘,由呈现线程从本地缓存中获取数据进行显示。这样,已经取出并缓存的数据就能快速呈现,不再有等待感;而取数线程所涉及的 SQL,在数据库中保持同一个事务,也不会有不一致的问题,数据库分页机制的两大问题(SQL 分页数据不一致、翻页效率差)都可以完美解决。
采用该机制,首页可实现秒级响应,缓存是在硬盘,内存占用小,可有效避免内存溢出。
另外,该机制同样支持非 SQL 数据源,包括文件数据源、noSQL 数据源、接口数据源等。
同时,报表格式上支持明细大报表、带汇总及分组大报表等,具体做法这里不再赘述,有更详细的文章介绍: 如何实现海量数据清单和分组报表
用例及测试结果
用例
通过以上了解的各产品支持情况,我们用大家都支持的大数据明细报表做个对比,看看首页呈现、翻页等的效率及体验。
数据库:MySQL 5.7
“各城市产品销售表”,620 万条 *6 列数据。
JVM:可用 1G,数据无法全部加载。
测试结果
报表按照每页 30 行 *6 列呈现。
从测试结果可以看出,润乾的首页加载及翻页体验最好,均可做到秒级响应。
帆软次之,看测试结果的话,新计算引擎体验上比行式引擎要好,但是目前功能不完善,如分页仅支持按页面大小,不支持其他方式等。在后面测试分组报表时也对这些不完善得到了印证,查询靠后的页码时,因 SQL 时间执行过长挂掉了,即便改了系统等待 SQL 执行时间,那也没法用了,等待时间太长,体验太差。这些问题在帆软官方客服那里也能被确认,新计算引擎新推出不久(看文档,貌似也近一年时间了),功能不完善,很多都是需要优化的状态。
Smartbi 也是数据库分页机制,但表现很差(尝试降低查询总数据量到 26 万,也需要 25s 左右),按测试用例结果来看,几乎是没法用的。
分组报表
Smartbi 直接不支持分组大报表,帆软在翻页时几乎没法用,只有润乾可以正常实现,这样就无法实施对比了。润乾实现方法可参考: 海量清单与分组报表的实现
性能测试结论
本篇之前还有三篇材料:
报表工具选型对比系列 - 多源关联性能
报表工具对比选型系列 - 容量及相关性能
报表工具对比选型系列 - 页面渲染性能
我们从四个方面对这三款报表工具进行了深入的性能测试对比。基本上每篇的结论都相同,即润乾报表的性能和容量最好、内核引擎最优;帆软次之,每个对比项上均有差距,但大部分项目差距并不算大。这两款均可以算作第一档次的报表工具,基本可以胜任大部分大容量和高性能场景。而 Smartbi 在性能容量方对比润乾和帆软则有明显的差距,面对大容量和高性能场景只能勉强甚至无法应对,能力要弱一个档次。