papi酱|关于OLTP 和OLAP 干货知识分享( 二 )


CUBE是什么
大家可以想象一下 , BI前端可视化分析工具 , 或者报表工具从数据仓库取数去分析展现 , 会不会遇到一些查询性能的问题 , 这些问题都是怎么来的 。
简单来说 , 分析页面刷新 , 前端浏览器不管是报表数据集模式 , 还是BI分析模型模式都会有一条SQL语句跑到服务器端去做数据查询 , 这个查询如果是BI的话就是到数据仓库上面去查 , 如果是数据集报表的话可以是从数据仓库 , 也可以是原始的业务系统数据库 , 总之有一条SQL语句要执行 。

第一种比如方式A返回的是大宽表到前端 , 数据量很大 , 前端再计算函数、慢慢渲染数据才展现出来 。
第二种比如方式B返回的查询汇总之后的结果 , 数据量很小 , 前端基本上不用做什么渲染数据就出来了 。
方式A的时间损耗在哪里呢?不是在数据库服务器查询上 , 因为SQL可能很简单 , 时间的损耗大部分是在从服务器端往浏览器通过HTTP连接返回、IO开销上 , 以及前端函数聚合汇总、解析和渲染上 。 B的时间损耗在查询阶段 , 因为SQL有大量的汇总 , 时间损耗在这个地方 , 减少了数据的返回量 , 前端函数基本上不用怎么处理 , 页面渲染也会很快 。
所以 , 大家看到了没有 , 方式B是对方式A的一种性能优化 。 如果把这种优化提前的比如在ETL调度中实现 , 头一天晚上先算好 , 把该聚合的数据聚合好先存到数据仓库中的某一张表里面 。 除了需要看明细数据的这种查询场景 , 其它的任何查询就直接从这张已经提前算好的表里面取数就可以了 。 整个的复杂的聚合过程不是在BI报表分析的时候再来计算 , 而是提前算好、存储 , 用的时候直接把聚合后的结果拉出来使用 。 大家看 , 多了一张表、多了一份存储空间 , 但是却把整个查询、聚合计算的时间给省下来了 , 这个过程就是我们经常讲到的“空间换时间”的概念 。

但是也有一个问题啊 , 数据聚合的结果存放到数据仓库中 , 这种数据的格式、形式是不是也相当于提前固化了 。 比如之前发过去的SQL查询返回的就是一张事实表 , 里面的度量是固定的 , 分析的维度属性也是固定的 。 如果现在用户改变分析维度或者指标呢?这张事实表就不能用了 , 新发起的查询就得像前面方式A提到的一样来处理 , 这样性能就又下降了 , 于是又得为这种新的查询聚合结果集再提前固化一张数据集市表 。 这样的场景多了 , 维护就非常的麻烦 。
所以数据人员就在想 , 如果我们能够提前把所有可能分析的维度和维度属性Dimensionand Attribute和所有可能分析的度量Measure全都组合好 , 全部算出来把结果提前存储起来 , 这样后面不管什么样的用户用什么样的维度和度量(指标)组合分析 , 都不需要临时计算 , 直接去结果 , 这样性能是不是就可以实现百倍、千倍甚至万倍的提升了?确实如此 , 因为你还要考虑到并发查询的问题 。
这样一做 , 就是一个更大范围的用空间换时间的过程 , 这个过程就是OLAP CUBE多维立方体的设计思想来源和原理 。
OLAP CUBE是如何来实现的
比如时间、区域、产品和销售收入这三个维度和指标的组合 。 它会先跑一遍SELECT SUM(收入)FROM表GROUP BY时间 , 接着就是SELECT SUM(收入)FROM表GROUP BY时间、区域 , 接着就是SELECT SUM(收入)FROM表GROUP BY时间、区域、产品 , 然后就可以是SELECT MAX(收入)FROM表GROUP BY时间、区域、产品 , 就是把各种聚合函数、各种指标、各种维度、各种维度属性的查询SQL全都执行一遍 , 把结果存储起来管理起来 , 就变成了一个多维立方体就是CUBE 。