开源SPL提速银行POS机交易报表30+倍

看看问题

S银行POS交易情况报表很慢,业务人员要等待一个多小时(3700秒)才能看到结果,严重影响业务。报表表样如下:

..

解决步骤

首先,要理解业务和计算特征。POS交易情况表连接数据库取数,定义了4个数据集,分别对应4SQL

POS1 数据集为例,脱敏之后的 SQL 语句如下

SELECT C_M,

       SUM(CASE

             WHEN C_FLAG = '0' AND C1_FLG != '1' THEN

              1

             ELSE

              0

           END) AS CNT1,

       SUM(CASE

             WHEN CR_FLAG = '1' AND C1_FLG != '1' THEN

              1

             ELSE

              0

           END) AS CNT2,

       …

       SUM(AMT) AS AMT

  FROM SHOP_DETAIL

 WHERE

T_CODE not in ('03')

 AND DAY_ID >= ?

 AND DAY_ID <= ?

 AND C_M in (SELECT C_CODE

               FROM ORG_LEVEL

              WHERE C_M_B = ?

                AND CTYPE = '6')

GROUP BY C_M

 

报表的设计界面如下图:

..

报表工具对于多个数据集是顺序计算的,即先后执行ds1ds2POS1POS2,总时间是4SQL的执行时间之和。然后再将4个结果集在报表单元格中进行格间计算,完成关联、汇总,最后呈现出结果报表。例如,上图中的B5单元格,POS1数据集就要与A5中的ds2关联。

 

第二,找到性能瓶颈,确定优化思路。数据集ds1ds2POS1POS2结果条数都不是很多,但是需要关联多次。

报表工具只能用单元格运算来描述多个数据集的关联关系,也只能用遍历的方式实现计算,复杂度高、性能差。要想办法降低复杂度才能提高性能。可以将4个数据集的关联计算从报表中移出,放在数据准备阶段进行。这样做,就可以针对整体数据集执行HASH关联算法,效率要高得多。提前计算的时候,还可以采用内存指针引用的方式做HASH关联,进一步提高计算性能。

四个数据集执行时间都比较长,顺序执行时4SQL加起来时间就更长了。我们发现,后台数据库比较空闲,如果能采用并行提交SQL执行的方式,总的执行时间会减少很多,后台数据库负载压力增加也在可接受范围内。

 

第三,确定技术选型和实施方案。报表单元格中的关联计算要在数据准备阶段提前完成,最常见的做法是合并SQL,由数据库完成关联计算。但是,我们无法用SQL写出4个结果集全内存指针引用关联的脚本,也没办法实现子查询并行执行。实际测试结果也证明,合并起来的SQL执行时间还会超过4SQL依次执行的时间之和。而且,报表数据集对应的SQL都有几十行,如果将4SQL合并成一个,会有上百行,很难阅读和维护。所以,将4SQL合并,由数据库完成关联计算的办法无法有效提高性能,也不利于后期维护。

使用Java为报表开发自定义数据集接口,当然可以实现上述算法,但这些运算在Java中非常难写,仅一个HASH关联就要数百行代码,而且还不通用。过大的编码量会导致实现周期过长,还容易出现代码错误隐患,也很难调试和维护。

开源集算器的SPL语言提供封装好的函数,支持上述所有的算法,包括并行提交SQL和全内存指针引用方式关联,能够让我们用较少的代码快速实现个性化的计算。

 

第四,实现优化方案。编写SPL脚本,先用4个线程并行连接数据库,执行4SQL。并行执行的总时间,是最慢那个SQL的执行时间,基本上是原来4SQL依次执行总时间的四分之一。最后返回结果。

在报表工具中,连接数据库的4个数据集全部删掉,而使用 SPL 作为自定义数据集,调用编写好的SPL脚本,返回一个结果集ds1,相当于原来的ds1ds2POS1POS2。SPL 提供有标准JDBC接口,报表工具可以象调用存储过程一样调用SPL脚本,向报表工具返回关联好的结果集。

之后,报表工具就只需要对关联好的结果集进行汇总即可,避免了单元格中的关联计算。修改后报表设计界面如下图:

..

效果如何

经过几天时间的修改、测试,报表计算呈现的时间由原来的3700秒缩短为105秒,速度提高了35倍,效果非常明显。

从开发难度来看,SPL做了大量封装,提供了丰富的函数,内置了上述优化方案需要的基本算法。上述算法对应的SPL代码也只有十几行:

..

相比上百行的复杂SQL来说,SPL代码短很多,结构清楚、容易阅读,也更容易编写和修改。

后记

解决性能优化难题,最重要的是设计出高性能的计算方案,有效降低计算复杂度,最终把速度提上去。因此,一方面要充分理解计算和数据的特征,另一方面也要熟知常见的高性能算法,才能因地制宜地设计出合理的优化方案。本次工作中用到的基本高性能算法,都可以从下面这门课程中找到:点击这里学习性能优化课程,有兴趣的同学可以参考。

有了优化方案后,还要用好的程序语言来高效地实现这个算法。虽然常见的高级语言能够实现大多数优化算法,但代码过于冗长,开发效率过低,会严重影响程序的可维护性。SPL 是个很好的选择,它有足够的算法底层支持,代码能做到很简洁,还提供了友好的可视化调试机制,能有效提高开发效率,以及降低维护成本。

我们怎样把 W银行预计算固定条件查询优化成实时灵活条件查询

我们怎样把 P保险公司 2小时的跑批优化成 17分钟

我们怎样把 T银行贷款跑批任务提速 150+

我们怎样把 B银行自助分析从 5并发提升到 100并发

我们怎样把 S银行手机账户查询从预先关联变成实时关联

我们怎样把 C保险公司团保明细单查询提速 2000+

我们怎样把 L 银行贷款协议跑批速度提高 10+ 倍

我们怎样把 X 银行用户画像客群交集计算提速 200+ 倍