级,时间维度的深度为4,地区维度的深度为4,产品维度的深度为3,那么我们从最底层的层级进行组合,一共包含时间维度的最底层级别包含120个成员,最底层包含5000个成员,产品维度最底层级别包含500个成员,那么可能的组合值就是120*5000*500=3亿个组合元素,这是最底层的组合元素,这些所有的组合可以看成一个长为120,宽为500,高为5000的立方体,这3亿个元素就是整个立方体,这个立方体中每一个单元里面包含每一个组合(月=xxx,城市=xxx和产品商标=xxx)的聚合值,一个cell包含所有的度量值,这样整个立方体就建立起来了,这个立方体是全量的值,其他的组合值可以都可以通过将该立方体的某一个子立方作为一个cell进行计算,例如我们要计算年份为1997,国家为中国,产品类型为食品的销售总额,那么就相当于将1997年下的所有月份(12个)、中国的所有城市(假设100个)和产品类型为食品的所有商标(假设为50个)所有组合的聚合值,也就是12*100*50=60W个 cell进行组合成的新的cell作为返回的结果。如果我们想要缓存整个cube,最好的情况下我们还是需要缓存所有最低级别所有成员的组合(因为从高层级得不到低层级的信息,除非从数据源获取),这个代价还是相当大的,一般情况下我们需要对成员进行建索引(为每一个成员制定下标),然后通过下标的组合作为key,度量值 的组合作为value进行缓存,但是当数据源哪怕插入一条数据都会改变整个cube中的大量的cell值,这个增量计算还是相当可怕的。
在不考虑增量计算的情况下,其实这个还是缓存量和查询速度的博弈,如果缓存量不够,势必会缓存一些高层级,这样对于底层级的查询就需要走数据源,性能就差,如果查询缓存底层级成员的组合那么所有的查询都不需要再走数据源,而是直接在内存中计算。当然最好的办法还是需要判断一下最常用的层级和每一个层级的成员个数,如果某一层级的成员个数过多则不适合缓存,如果查询频率比较高的层级则更适合缓存。
任务艰巨啊,还是先一步一个脚印的走吧,首先第一步将mondrian的缓存移出程序并且考虑一下缓存结构是否有比较再进行优化,第二步可以分析一下mondrian的执行SQL,看一下有没有优化的空间,第三步是进行预计算保存在缓存中,当然这时候暂时不考虑到动态的增量更新,最后再考虑如何做到增量计算。
?
|