金蝶云-星空 报表计算时涉及大量的公式计算。
在报表发起计算之后,我们会先对整个报表上面的公式提取并做分析,具体步骤如下:
(1) 把所有的ACCT公式作为一组;
(2) 把ACCT公式涉及的账簿、科目编码、取数类型、年度、期间搜集起来,形成参数集合。例如本次计算涉及001,002这几个账簿,最小科目是1401、最大科目是5201,取数类有Y-期末数、C-本期发生数,币别编码是01-人民币,年期范围是2020年1月到2020年5月。
(3) 把合并之后的参数拼成一个SQL从后台数据库取数。这样只需一次数据库查询就能得到报表计算所需的全部数据,大大减轻了数据库压力。
(4) 根据查询结果的数据结构构建内存数据库,并把数据批量导入内存数据库。
(5) 根据每个公式的查询特点对内存数据表创建索引。
(6) 每个公式再根据自己的参数拼接过滤条件从内存数据库中取自己的数据。如ACCT("001","1401:1408","Y","01",2020,1,1),该公式会从内存数据库中查询账簿编码为001,科目范围是1401:1408,数据类型为Y-期末数,年度是2020,期间为1的期末余额。
(7) 最终系统会把计算结果生成一个数据字典返回到客户端,并把计算结果赋值给报表控件。这个数据字典的Key是公式名称及参数组成的字符串,Value就是公式计算的结果。以ACCT("001","1401:1408","Y","01",2020,1,1)为例,终止的结果是Dictionary[ACCT_001_1401:1408_Y_01_2020_1_1)]=1000.00。
在没有实现内存数据库之前,4、5、6步利用的是DataTable的计算功能。
数据量小的时候用DataTable还好,如果数据量达到10万,DataTable的计算性能几乎无法忍受。
启用内存数据库之后,报表的计算性能提升10倍以上。
目前启用内存数据库只对Acct、自定义函数有效。后面我们会把所有的报表计算都改为使用内存数据库。
推荐阅读