大厂的物化视图实践

153 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情

并非每个数仓都是列式存储,但对于临时分析查询,列式存储快得多,所以才迅速普及。

数仓的另一个有趣点:物化聚合。数仓查询通常涉及聚合函数,如SQL中的COUNT、SUM、AVG、MIN或MAX。若相同的聚合被许多不同的查询使用,每次都处理原始数据就显得很浪费。何不缓存查询最常使用的一些计数或总和?

创建这种缓存的一种方式:物化视图(Materialized View)。关系数据模型中,它通常被定义为标准(虚拟)视图:一个类似表的对象,其内容是一些查询结果。

不同在于:

  • 物化视图是查询结果的实际副本,并被写盘
  • 虚拟视图只是写入查询的快捷方式。从虚拟视图读取时,SQL引擎会将其动态扩展到视图的底层查询,然后处理扩展查询

当底层数据变化,物化视图也得更新,因为它是数据的非规范化副本。数据库可自动执行,但这样更新影响写性能,所以OLTP数据库中不经常使用物化视图。对读密集的数仓,物化视图更有意义。

物化视图的常见特例称为数据立方体或OLAP立方体,不同维度分组的聚合网格:

图12:数据立方的两个维度,通过求和聚合

想象每个事实都只有两个维度表的外键,图12中即为日期和产品。每个单元格即是date-product组合的所有事实的属性(如net_price)的聚合(如SUM)。然后,沿每行或每列应用相同的聚合操作,得到一个维度减少的聚合(按产品销售额而不管日期,或按日期的销售额而不管产品如何)。

物化数据立方体的分析:

优点

某些查询会很快,因为已被预先计算。如若想知道昨天每个商店的总销售额,只需查看对应维度的总和,而无需扫描数百万行。

缺点

数据立方体缺乏像查询原始数据的那种灵活性。如无法直接计算成本超过100块的物品所占销售额比重,因为价格不是其中一个维度。因此,很多数仓试图保留尽可能多的原始数据,仅当数据立方体可以对特定查询显著提升性能时,才采用多维数据聚合。