多维分析预汇总应该怎样做才管用?_不同维度的数据如何汇总分析

| — | — |
| | A |
| 1 | =file(“orders.ctx”).open() |
| 2 | =A1.cuboid(cube1,odate,dept;sum(amt)) |
| 3 | =A1.cuboid(cube2,month@y(odate),dept;sum(amt)) |
| 4 | =A1.cgroups(dept;sum(amt);odate>=date(2018,1,22)&&dt<=date(2018,9,8)) |

cgroups 函数增加了条件参数,SPL 发现有时间段条件和更高层次的预汇总数据,则会使用时间段预汇总机制来减少运算量。本例中,就会分别从 cube1 和 cube2 中读取相应数据再来汇总。

SPL硬遍历

预汇总能够应对的场景仍然很有限,要做出灵活的多维分析,还是要指望过硬的遍历能力。多维分析运算本身并不算复杂,遍历计算主要是针对维度的过滤。传统数据库只能用WHERE硬算,维度相关的过滤也当作常规运算,不能获得较好的性能。SPL提供了多种维度过滤机制,可以满足各类多维分析场景的性能要求。

布尔维序列

多维分析中最常见的切片(切块)是针对枚举维度进行的,除了时间维度几乎都是枚举维度,如产品、地区、类型等。常规处理方式用SQL表达大概这样:

SELECT D1,…,SUM(M1),COUNT(ID)… FROM T GROUP BY D1,…
WHERE Di in (di1,di2…) …

其中的Di in(di1,di2)就是过滤字段在一个枚举范围内取值。在实际应用中,“按照客户性别、员工部门、产品类型等切片”都属于枚举维度切片。常规的IN方法需要进行多次比较判断才能筛选出符合条件的数据(切片),性能很低,IN的取值越多性能就越差。

SPL将查找运算转换成取值运算来提升性能。先将枚举维度转换成整数),如下图将事实表中的维度D5取值转化成在维表中的序号(位置):

image

然后在查询时将切片条件转换成布尔值构成的对位序列,在比较时就可以直接从序列指定位置取出值(true/false)判断结果,快速完成切片操作。

image

SPL数据预处理代码示例:

A
1=file(“T.ctx”).open()
2=file("T_new.ctx”).create(…)
3=DV=T(“DV.btx”)
4=A1.cursor().run(D=DV.pos@b(D))
5=A2.append@i(A4)

A3读取维表,A4 利用 DV 把维度 D 转换成整数。DV 将被另外保存供查询时使用。

切片汇总:

A
1=file(“T.ctx”).open()
2=DV.(V.pos(~))
3=A1.cursor(…;A2(D))
4=A3.groups(…)

A2 将参数 V 转化成一个和 DV 同长的布尔值序列,DV 的成员在 V 中时,则 A2 对应位置的成员将非空(判断时起到 true 的作用),否则填成空(也就是 false)。然后在遍历切片时,只用已经转换成整数维度 D 作为序号去取这个布尔值序列的成员,如果非空就表明原来的维度 D 是属于切片条件 V 的。序号取值的运算复杂度远远小于IN比较,大幅提升切片性能。

SPL优秀的硬遍历能力在实践中应用效果明显,在开源 SPL 提速银行用户画像客群交集计算 200+ 倍 这个案例中,借助布尔维序列、游标前过滤等硬遍历技术将银行用户画像客群交集计算效率提升了200倍以上。

标签位维度

多维分析中还有一种特殊的枚举维度常用于切片(很少用于分组统计),其取值只有是/否或true/false两种情况,被称为标签维度或二值维度,比如人员是否结婚、是否上过大学、是否拥有信用卡等。标签维度切片属于过滤条件中的是否型计算,用SQL表达大概这样:

SELECT D1,…,SUM(M1),COUNT(ID)… FROM T GROUP BY D1,…
WHERE Dj=true and Dk=false …

标签维度很常见,对客户、事物贴标签是当前数据分析的重要手段,现代多维分析的数据集常常会有几百甚至上千个标签维度,如果将这种维度当作普通字段处理,无论是存储还是运算都会造成很多浪费,难以获得高性能。

标签维度只有两种取值,只要一个位就可以存储了。一个 16 位的整数可以保存 16 个标签,原本要用 16 个字段来存储的信息用一个字段就够了,这种存储方式称为标签位维度。SPL提供了这种机制,这将大幅度减少存储量也就是硬盘读取量,而且整数也不影响读取速度。

举个例子,这里我们假设总共有8个二值维度,用整数字段c1存储8位二进制数表示。要用按位存储的方法计算二值维度切片,需要先将事实表预处理为按位存储。

image

处理后的事实表,第一行c1为AFh,转换为二进制数为10100000,表示D6、D8是true,其他二值维度是false。然后就可以进行按位计算实现二值维度切片了。

image

前端传入的切片条件为"2,3",也就是要过滤出第2个二值维度(D7)和第3个二值维度(D8)值是true,其他二值维度是false的数据。

SPL代码示例:

AB
1=“2,3”=A1.split@p(“,”)
2=to(8).(0)=B1.(A2(8-~+1)=1)
3=bits(A2)
4=file(“T.ctx”).open().cursor(;and(c1,A3)==A3)
5=A4.groups(.D1,.D2,.D3,.D4;sum(~.M1):S,count(ID):C)

8个是否型条件过滤,只要做一次按位与计算即可实现。这样就将原来二值维度的多次比较计算,转换成了一次按位与计算,因此性能会有很明显的提升。多个是否值转换为一个整数,还可以减少数据占用的存储空间。

冗余排序

冗余排序是利用有序来加快读取(遍历)速度的优化手段,具体实现时按维度 D1,…,Dn排序后存储一份,再按 Dn,…,D1排序存储一份,数据量会翻倍,但还可以接受。对于任何维度 D,总能有一个数据集使 D 在其排序维度列表中的前半部分,如果不是第一个维度,切片后数据一般不会能连成一片区域,但也是由一些相对较大的连续区域构成的。在排序维度列表中越靠前的维度,切片后数据的物理有序程度就越高。

image

在计算时,使用一个维度的切片条件来筛选就可以了,其它维度上的条件仍然用遍历计算。多维分析时某一个维度上的切片,常常都能使涉及数据量减少数倍或数十倍,在其它维度上再利用切片条件的意义就不大了。有多个维度上都有切片条件时,SPL会选择切片后范围和总取值范围相比较小的维度,通常意味着过滤后的数据量更小。

SPL的cgroups 函数中实现了这个选择,如果发现有多个预汇总数据按不同维度排序的,且有切片条件时,则会选择最合适的那个。

A
1=file(“T.ctx”).open()
2=A1.cuboid(cube1,D1,D2,…,D10;sum(…))
3=A1.cuboid(cube2,D10,D9,…,D1;sum(…))
4=A1.cgroups(D2;sum(…);D6>=230 && D6<=910 && D8>=100 && D8<=10 &&…)

cuboid 建立预汇总数据时分组维度的次序是有意义,针对不同的维度次序会建立出不同的预汇总数据。也可以人为用代码选择合适排序的数据集,以及存储更多种排序的数据集。

此外,SPL中还提供了很多高效运算机制不仅适用多维分析,还可以面向其他数据处理场景,如高性能存储、有序计算、并行计算等等,结合这些能力可以获得更高效的数据处理体验。

诚如前面所说,预汇总只能解决多维分析中一小部分相对简单固定的需求,其他大量常见的需求还需要使用诸如SPL这样的计算引擎实施高效硬遍历才能很好满足,在优秀的硬遍历能力基础上再结合SPL提供的部分预汇总与时间段预汇总功能就可以更好地满足多维分析在性能和灵活性方面的要求,同时将存储成本降到最低。

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值