预算聚合引擎模型分析

预算维度:


预算组织:189
预算期间:50
预算版本:7
预算情景:15
预算要素:11
预算科目:1540
预算币别:3
预算状态:3


辅助维度:


板块:8
区域:5
项目:2536
辅助核算:82
对方单位:8
预算维度1:2
预算维度2:2


合并维度:8


我们是基于不同维度成员的笛卡尔积来构建一个多维立方体的模型来处理的,
理论上,CubeCellSize = |DIM1|*|DIM2|*DIM3|*...|DIMm| 


在程序上,我们聚合引擎是通过递归遍历Member成员,这样导致的结果,在CubeCellSize的量级在14次方的时候,在时间上,程序还能在10秒之内完成,接下来,量级每增加一位,会导致性


能急剧下降,比如:1000 减少一个量级到 100,这样是减少了 900,而100000000减少一个量级到10000000,中间减少了90000000,这样的话,就是在维度成员的笛卡尔积小的时候,成员的


减少还没有明显的效果,但是在在维度成员到达我们用户所能接受的边界的时候,这样减少成员会带来明显的效果。


所以,引擎最初的处理是缓存所有的Member的HashCode为Key值,该成员的值Value,如果该值为空,那么给一个默认的NULL值来标识某个成员的值为空,这样能够减少构建CUBE空间所消耗内


存空间的大小,如果值不为空,那么我会将这个值缓存在PincacheMap中,这个Map会缓存多维空间坐标所对应的值,当前我们在不断递归地去找非空的数值进行聚合处理的过程中,当我们遇


到之前已经算过的聚合值的成员的时候,这个时候,我们是不需要再去重新递归一遍该成员所有的下级成员的,因为某些成员我们已经递归计算过了,所以这种情况下,我们可以直接取缓存


中的值,这样的话,能够避免大量的冗余计算量。


另外,对于我们构建CUBE多维立方体,我们假如想基于当前构建的立方体去进行二次计算,这个时候我们需要引入计算单元的概念,CellA = CellB+CellC,CellA = CellD,在这个时候,我


们在同一个单元格中可能会存在多个计算公式,我们可以直接取最后一个计算公式的值进行,因为没有必要去计算之前的计算公式,之前计算的结果都会被最后的一个计算公式所覆盖掉,所


以,没有必要去计算这部分内容。


假如存在  CellA = CellB,CellB = CellC+CellA 的情况的话,这种情况cell个计算会陷入无限递归地错误,导致堆栈深度错误,所以我们在定义计算单元的时候,我们需要避免出现这种情


况的发生。


1.削减维度成员 或者 削减维度


接下来,就是讲对此次优化内容的理解,在理想的聚合模型下,我们是不能去去选择我们的CUBE多维空间,这个模型都是基于我们在定义scheme文件时,给予引擎的逻辑模型,这个模型是基


于树形结构,我们引擎读取的数据全部是基于我们的基础维度表中的基础资料,以及我们的事实表中的事实数据,这样构建出我们的立方体。但是,这样做,构建出来的立方体是一个全集,


但是在我们业务报表里面,我们通常只需要在多个维度中的一个子集中去进行我们的数据的聚合处理,例如,我们在组织维度上,我们通常只需要在某部分组织上去进行数据的聚合处理,因


为在业务上,系统是有组织架构控制的,不同的组织只能看到所在组织级别上的数据,而在这个过程中,我们是不需要去站在集团上去进行数据的聚合操作的。所以,在这个过程中,我们预


算聚合逻辑中,我们使用两种方式来处理,一种是通过在cube中去除组织维度,然后我们在事实表中按单组织(通过当前组织的CLOSURE表,找到该组织的所有下级)进行分割,将所有的数据


通过期间要素版本情景进行分组求和,这样的话,能够去除一个组织维度,能够加快引擎聚合的时间。第二种方式就是,将组织维度加入到CUBE中,这样导致的结果是组织维度成员全部加入


CUBE中,而组织的量如果超过2000,会拖慢引擎聚合的速度的,这样做的优势就是可以多组织进行一次查询,相比单组织进行多次处理,这样批量处理的话,在某种程度上,是更快的。


另外在上港合并业务中,虽然有15个维度,但是,在业务上,存在部分维度只是使用了汇总成员,所以,在这种情况下,我们是不需要这个汇总成员的下级成员进行聚合的,这里我们的汇总


成员就是明细,所以在这种情况下,我们对只使用了一个维度汇总成员的维度成员进行了削减操作,这样的话,我们能够大大减少成员数量,另外我对辅助维度成员进行了组织隔离,当站在


下级组织的时候,只能看到下级组织拥有的辅助维度成员,把这部分成员加入到CUBE中,这样能够在一定成员缩小CUBE大小。




同样的道理,我们在版本维度上,我们在一张报表里面,通常都是涉及同一个版本,而不会涉及到多版本的相互处理,所以,我们在版本维度上,我们也将版本维度去除掉。


在币别维度上,由于同一张表,如果只涉及到单币别的话,我们也可以将币别维度进行削减。


这样,我们能够 将 CUBECELLSIZE 的大小 削减到 币别成员(3用户成员+3引擎成员) * 版本成员(3个引擎成员+ 7个用户成员)= 60 倍。

猜你喜欢

转载自blog.csdn.net/z123271592/article/details/78667093
今日推荐