多维分析的后台性能优化手段


内容来源:本文转载自数据蒋堂公众号,经受权发布!
性能优化

阅读字数:2969 | 5分钟阅读多线程

摘要

多维分析法是高级统计分析方法之一,就是把一种产品或一种市场现象,放到一个两维以上的空间坐标上来进行分析。并发

多维分析就是针对一个事先准备好的数据立方体实施旋转、切片(切块)、钻取等交互操做的过程,常常也被直接称为OLAP。它的后台运算在结构上很简单,若是用SQL语法描述,大致形式为:函数

SELECT D,..., SUM(M), ... FROM C WHERE D'=d' AND ... GROUP BY D,...性能

即对立方体按某些维度分组汇总某些测度。其中C是数据立方体,D,...是选出维度,M,...是聚合测度,聚合函数也能够不是SUM。D'是切片维度,切块时条件为D IN (d,...),WHERE中还能够增长针对某些测度的条件,通常也就是选出某个区间内的值。测试

OLAP须要即时响应,对性能要求很高,而这个运算形式虽然很简单,但数据量大时的计算量也不小,若是不设法优化,效率就可能不好。下面咱们介绍多维分析后台建设时几种常常被采用的性能优化手段。优化

预先汇总

预先汇老是早期OLAP产品经常使用的手段,简单地就是拿空间换时间。把部分或者所有维度组合(GROUP BY子句)的汇总值(SELECT中的聚合测度)先计算出来保存,之后的计算能够直接取出或从这些中间结果再计算,性能会好不少。线程

预先汇总占用的空间有点大。若是保存所有维度组合,通常应用场景下(十几到几十个维度,维度取值范围在几到几十之间),简单计算可知,空间占用会比原始立方体大数倍到数十倍((k1+1)*(k2+1)*...与k1*k2*...之间的比,还要考虑多种聚合函数)。虽然要保证即时响应时立方体都不会太大,但再大几十倍常常也仍是难以接受的。设计

折衷办法是只保存部分维度组合。OLAP过程当中在界面上呈现出来的分组维度(GROUP BY子句)不会太多,能够只汇总全部m个维度的组合,在m不太大时(通常不超过5),空间增加还能够容忍,而用户的大多数操做均可以获得较迅速响应。code

麻烦在于,部分汇总解决不了针对其它维度的切片条件,钻取动做就是以切片为基础的。并且,即便全量汇总也没法处理测度上的条件(好比销售额超过1000元的统计),而多维分析时经常容许这些动做,甚至聚合函数也可能带有条件(只合计100元如下的费用),这些都没法使用预先汇总的结果。

预先汇总只能解决小部分最多见的计算,更多的状况仍是要靠硬遍历。

分段并行

多维分析本质上是过滤和分组汇总,这种运算很容易并行。只要简单地数据拆成多段后分别处理,收集到结果再汇总。各个子任务之间没有依赖关系,不管是单机多线程仍是集群多机或者综合有之,都不难实现。

多维分析的结果是要呈现给人看的,而人能够观察的数据量远远小于现代计算机的内存。能够放入内存的小结果集不须要和外存交换,程序设计复杂度较低,运算性能也好。若是运算时发现结果集太大是能够直接报告给界面相应信息并停止。

实践测试代表:多线程计算时,不要采用各子任务向同一个结果集汇总的方案,这样看起来会减小内存占用(各子任务共用一个最终结果集),但多线程抢占同一资源须要的同步动做会严重影响性能。

线程数也不是越多越好,显然超过CPU核数就没有意义了。若是数据在外存,还要考虑硬盘的并发能力,通常会比CPU核数小不少,具体合适的数值须要实际测试才知道。

在数据再也不变化时分段也容易,按记录数切分后设置分段点便可。数据可追加时要作到较平均的分段会有些麻烦,之后再另外撰文陈述。

对于单个计算任务,并行后经常有数倍的性能提高。可是,OLAP操做自己就是个并发性事务,即便用户数不大,也足以抵消并行计算带来的性能提高。

还要再想办法。

排序索引

没有切片的汇总运算老是要涉及全量数据,若是不是预先汇总,也没什么办法再减小计算量了。但有切片运算时(钻取动做),若是数据能合理组织,就未必要遍历全部数据了。

若是咱们为维度D创建索引(即把各记录的D值及记录位置按D值排序),那么涉及D的切片条件就能够迅速定位到相应的记录上(简单二分法),不须要遍历全量数据,计算量经常会有数量级的减小(取决于D的取值范围)。理论上咱们能够为每一个维度都创建索引,这个成本并不算高,这样只要涉及有切片时,性能就会大幅提高。

须要指明的是,为多个维度D1,D2创建的多字段索引用处并不大,它不能用于迅速定位只有D2的切片,只能用于对D1,D2都有切片条件的状况。在选择取值范围最大的那个切片维度用于定位后,计算量减小已经不少了,其它维度的切片能够仍用遍历手段。

不幸的是,这种原始方案只适用于能够频繁小量访问的内存数据。若是数据量大到必须放在外存中(而这是常常发生的),按索引大量取出实际上并未连续存储的数据时,性能并不会有明显提升。外存数据必须被真实排序、保证相应切片的数据是连续存储的,性能提高才会有效。

若是对每一个维度都作排序,那至关于数据要被复制若干倍,这个成本就有点高了。

一个折衷的办法是把作两个,按维度D1,...,Dn排序一次,再按Dn,...,D1排序一次,数据量只是翻倍,还能容忍。总能找到一个切片维度在两个维度排序列的前半部分,这样该维度切片的数据仍是基本连续的,性能提高仍会较为明显。

列存压缩

对付多维分析还有个大杀器:列式存储。

多维分析的立方体中字段(维度和测度)经常都不少,几十个上百个都很正常,但同时须要取用的字段并很少,若是不算切片维度,一般也就5个左右或更少。而切片能够用上面的索引方案解决,实际要遍历的字段也仍然很少。

这时候列存就会有巨大优点了。外存计算的IO时间占比至关大,减小数据读取量比减小运算量经常能更有效地提升性能。一个100个字段的立方体,若是只取5个字段时,IO开销只有1/20,这会带来数量级的性能提高。

列存还有个优点是能够压缩数据量。若是按前述所说将数据按维度D1,...,Dn排序存储,咱们会发现D1在连续许多记录中取值都相同,D2也是相似,但程度会弱一些,越日后的维度连续相同的程度越弱,Dn就会几乎没有相同连续值。连续相同的值不必重复存储,能够只存一次并记录个数,这样将能够进一步减小存储量,也就是减小外存IO访问量,从而提升性能。

固然,列存也并不全是好处。

由于不减小计算量,列存对于内存数据用处不大。不过压缩存储方式仍然有意义,能够减小内存占用。

使用列存会使分段并行及创建索引的处理变得更复杂,各个列须要同步分段才能并行处理,索引也须要同步指向全部列,而使用压缩机制后同步更为麻烦。不过,总得来说,在数据已经肯定再也不变化时,虽然麻烦,但难度并不算大,只是别忘处理了就行。

列存还会加大硬盘的并发压力,在总字段数很少或取用字段较多时并无优点。对于机械硬盘,若是再使用并行手段进一步加重并发压力,极可能致使性能不升反降的结果,对于易于并发的固态硬盘使用列存较为合适。

相关文章
相关标签/搜索