【性能优化】8.1 [多维分析] 部分预汇总

 

【性能优化】7.4 [归并与连接] 附表

8.1 部分预汇总

多维分析后台的运算本质上就是个分组汇总,前面讲过的分组方法都可以利用。但当数据量非常大的时候,想做到即时响应也不是很容易的事。

预汇总是个容易想到的方法,即事先把各种汇总结果计算好,前端请求时就可以直接返回。也就是用空间换时间,相当于把遍历问题转化为查找问题,理论上是可以做到即时响应了。

但是,全量预汇总基本上不可行,简单计算一下就能知道。

50 个维度做全量预汇总,需要 250 个中间结果集,保守估算也要上百万 T 的容量,这就没有可操作性了。即使只预汇总其中 10 个维度(观察维度加切片维度,10 个不算多了),也仍然需要数百 T 以上存储空间,实用性很差。

可以做的只能是部分预汇总。即只预汇总部分维度的组合,前端有请求时,寻找某个条件预汇总数据再来汇总,这样大概能把性能平均提高数十倍,也常常能满足要求了。

预汇总哪些维度组合,一般是靠业务经验,也可以记录历史查询请求后统计分析,还可以动态产生新的并删除不常用的,这些都是工程手段,在算法方面没有太多可讨论的内容。

如果有多个预汇总数据,那么选择哪一个来应对前端请求呢?

假定前端请求针对维度 A,B 的统计值,那么找预汇总数据也中包括了维度 A,B 的就可以,如果有多个,则选择其中数据量最小的那个再计算即可。

这些逻辑都比较简单。

SPL 为组表提供了部分预汇总的功能:


A

1

=file("T.ctx").open()

2

=A1.cuboid(file("1.cube"),D1,…;sum(M1),…)

3

=A1.cuboid(file("2.cube"),D1,…;sum(M1),…)


使用 cuboid 函数可建立预汇总数据,需要指定预汇总数据的文件名 ,剩下的参数就和分组汇总一样了。

使用时也很简单:


A

1

=file("T.ctx").open()

2

=A1.cgroups(D1,…;sum(M1),…;file("1.cube"), file("2.cube"))

cgroups 函数就会按上述的逻辑自动寻找最合适的预汇总数据再计算。

预汇总方案很简单,但受限于容量,其应用局限也很多,只能应对最常见的情况。

如下几种情况都难以全面应用预汇总方案:

1) 非常规聚合:除了常见的合计、计数外,有些非常规聚合,比如唯一计数、中位数、方差等很可能被遗漏,也无法从其它聚合值计算出来。理论上有无数种聚合运算,不可能被预汇总。

2) 组合聚合:聚合运算可能组合。比如我们可能关心月平均销售额,这个值是将每天的销售额按月合计后再求平均。它并不是单纯的合计和平均,而是两种聚合运算在不同维度层次上的组合。这些也不太可能事先预汇总。

3) 条件测度:测度在统计时还可能带有条件。比如,我们想了解一下交易金额大于 100 元以上的订单销售额合计。这个信息也无法在预汇总时处理,因为 100 会是临时输入的参数。

4) 时间段统计:时间是个特别维度,它即可以枚举、也可以采用连续区间的方式来做切片。查询区间的起止点可能是细粒度(比如到某日),就必须用细粒度的数据再统计,而无法直接使用更高层的预汇总数据。

【性能优化】8.2 [多维分析] 时间段预汇总
【性能优化】 前言及目录