报表里有 4 个 SQL 数据集,SQL 在数据库里跑一共不到 10 秒,但报表查完很慢要几分钟,咋回事?

 

关键词: 润乾报表慢 报表性能低 帆软报表慢 BIRT 报表慢 JasperReport 慢 IReport 慢 数据库快报表慢

你要确认一下执行完 SQL 结果是否都加载了,像 PL/SQL Developer 查完就只加载部分。

不过报表运行时间肯定是要比数据库查 SQL 慢的,如果慢很多可能是因为在报表里关联多个数据集导致的。可以检查一下在报表单元格里是否有类似:ds2.select(name,id==ds1.cusid) 这样的表达式,表示数据集 2 和数据集 1 通过某个字段实现关联。

几乎所有报表工具在完成多数据集关联时都采用顺序遍历的方式实现,先拿一个数据集的第一条记录去第二个数据集中遍历查找符合条件的记录,然后是第二条,第三条…,数据量大的时候性能就会很低。画个图看一下:

png

在报表里关联这两个数据集就要遍历数据集 ds1 记录数(100 万)次数据集 ds2,总共比较 100 万 *1000 次。。。速度当然慢了。

要解决这个问题,得想办法把关联计算改到为报表准备数据那个阶段,方法有两个。

一、用 SQL 完成原来 4 个数据集的关联

写个复杂 SQL,把原来 4 个数据集的 SQL 整合成一句,让数据库完成关联计算(HASH JOIN),这样会快很多。当然这种做法有几个限制:

1、 不能跨库。如果原来的 4 个数据集来自不同数据库,就不能这么干了。异构源当然也不行;

2、 不能有存储过程。改造存储过程的成本太高,而且需要相应数据库权限;

3、 SQL 太复杂不好整合。有时报表的数据集 SQL 都很复杂,还带有很多参数(报表传过来的),很难整合到一起。其实这正是报表里要用多数据集的原因,报表工具支持多数据集会带来很多方便,但会影响性能。

二、直接用带强计算能力的报表工具

有一些报表工具带脚本计算能力,这样就可以事先关联完多个数据集。这样就改变了原来要么在数据库里关联(很多情况没法实现),要么在报表模板里关联(性能太低)的状况,性能往往能提升几倍到几十倍。

这个文章介绍了详细的实施过程: 如何提高多源关联报表性能 ,里面举的三个例子性能分别提升了 5 倍、26 倍和 44 倍,效果比较明显。

而且,这个工具有了脚本能力还支持跨库,文件、NoSQL 这些数据源,也能调用存储过程,解决了数据库面临的那些问题。