【性能优化】8.3 [多维分析] 冗余排序
8.3 冗余排序
无切片条件的汇总运算总要涉及全量数据。如果没有预先汇总,也没什么办法减少计算量了。但有切片条件时,如果数据能合理组织,就未必要遍历所有数据了。
简单在维度上建立索引会有些作用,但并不会太好。索引能够迅速定位满足条件的记录,但如果这些数据的物理存储位置并不连续,那么读取时仍然会有很多浪费,在目标数据过于分散时,未必比全遍历好多少,因为多维分析运算中,即使切片后要读出的数据量也常常很大,索引主要的应用场景还是选出少量数据。
如果数据存储时对某个维度有序,则可以用该维度的切片条件把目标数据限定在一个连续的存储区域,这样就不必遍历所有数据了,读取量就能有效减少。但是,理论上每个维度都可能有切片条件,如果把数据按每个维度都排序,那相当于要被复制若干倍,这样的存储成本就有些高了。
一个折衷的办法是存储两份数据集。按维度 D1,…,Dn排序后存储一份,再按 Dn,…,D1排序存储一份,数据量会翻倍,还可以容忍。对于任何维度 D,总能有一个数据集使 D 在其排序维度列表中的前半部分,如果不是第一个维度,切片后数据一般不会能连成一片区域,但也是由一些相对较大的连续区域构成的。在排序维度列表中越靠前的维度,切片后数据的物理有序程度就越高。
在计算时,使用一个维度的切片条件来筛选就可以了,其它维度上的条件仍然用遍历计算。多维分析时某一个维度上的切片,常常都能使涉及数据量减少数倍或数十倍,在其它维度上再利用切片条件的意义就不大了,实现难度却很大。有多个维度上都有切片条件时,通常我们会选择切片后范围和总取值范围相比较小的维度,这常常会意味着过滤后的数据量更小。
cgroups 函数中实现了这个选择,如果发现有多个预汇总数据按不同维度排序的,且有切片条件时,则会选择最合适的那个。cuboid 建立预汇总数据时分组维度的次序是有意义,针对不同的维度次序会建立出不同的预汇总数据。
也可以人为用代码选择合适排序的数据集,以及存储更多种排序的数据集。
冗余排序方法并不只用于多维分析,有过滤条件的常规遍历时也可以使用。只是多维分析中维度切片时相关特征会更明显,更适合把这个问题讲清楚。