异步物化视图概述

更新时间:
复制为 MD 格式

异步物化视图(Async Materialized View)是SelectDB提供的一种支持多表JOIN、异步刷新的物化视图,广泛用于复杂查询加速、数仓分层建设和湖仓一体查询加速场景。

使用场景

异步物化视图主要适用于以下场景:

  • 查询加速:对于包含复杂聚合、多表JOIN的高频查询,预先物化计算结果,查询时通过透明改写直接命中物化视图,大幅降低查询延迟。

  • 简化 ETL 流程在数据仓库建设中,利用物化视图对原始数据进行分层聚合和ETL处理,构建ODS、DWD、DWS、ADS等数据层,减少重复计算。

  • 湖仓一体查询加速:对于存储在Hive、Iceberg等数据湖中的外部数据,通过异步物化视图将热点查询结果缓存至SelectDB本地,利用SelectDB高性能引擎大幅提升查询性能。

  • 提升写入效率:通过减少资源竞争,物化视图能够优化数据写入过程,提高写入效率,确保数据的一致性和完整性。

使用限制

使用异步物化视图时,需注意以下限制:

  • 最终一致性:异步物化视图的数据与基表存在一定延迟(取决于刷新策略),不保证强一致性。对实时性要求高的场景,建议使用同步物化视图。

  • 窗口函数限制:物化视图定义SQL中若包含窗口函数,当前版本不支持透明改写,但支持直查(直接查询物化视图)。

  • JOIN表数量限制:透明改写要求物化视图定义中的JOIN表数量不超过查询中的JOIN表数量,否则无法完成改写。

  • 外表分区增量刷新限制:Hive外表从2.1版本起支持分区增量刷新;Iceberg、Paimon、Hudi3.1版本起支持分区增量刷新;JDBCES外表不支持分区增量刷新,刷新时需指定COMPLETE全量刷新。

  • 物化视图本身的数据模型:物化视图本身只能是明细模型(Duplicate Key),不受基表数据模型限制。

  • 集合操作与特殊语法限制:如果物化视图包含UNION ALL等集合操作、LIMIT、ORDER BY、CROSS JOIN,物化视图可以正常构建,但不能用于透明改写。

原理

MTMV(多表物化视图)

SelectDB的异步物化视图基于MTMV(Multi-Table Materialized View)框架实现。MTMV框架将物化视图的定义SQL(查询语句)与基表解耦,在后台异步执行刷新任务,将物化视图的数据更新为最新状态。每个物化视图都有独立的刷新任务(Job),由调度器管理执行。

刷新机制

异步物化视图的刷新过程如下:

  1. 刷新任务触发(手动/定时/ON COMMIT)。

  2. 系统检测基表数据自上次刷新后是否发生变化(仅支持内表和Hive外表)。

  3. 对于分区物化视图,仅刷新数据变化的分区,分区增量刷新;对于非分区物化视图,刷新全量数据

  4. 刷新完成后,更新物化视图的版本信息和状态(NORMAL/SCHEMA_CHANGE等)。

透明改写(SPJG算法)

SelectDB的查询优化器(Nereids)支持基于SPJG(SELECT-PROJECT-JOIN-GROUP-BY)模式的透明改写:当用户提交一个查询时,优化器会自动分析该查询是否可以被已有的物化视图满足,如果可以,则将查询路由到物化视图,而不执行原始查询,从而实现查询加速且无需修改业务SQL。

透明改写的判断逻辑包括:

  • 查询的输出列是否可以从物化视图的列推导得出。

  • 查询的JOIN关系是否被物化视图覆盖。

  • 查询的过滤条件是否在物化视图的数据范围之内。

  • 物化视图的数据是否处于有效状态(NORMAL)。

说明

只有状态为NORMAL的物化视图才能参与透明改写。若物化视图因基表Schema变更等原因状态变为SCHEMA_CHANGE,需等待下次刷新任务成功后恢复为NORMAL状态。

基于数据湖创建异步物化视图

SelectDB支持基于外部数据源(通过Catalog接入)创建异步物化视图,实现湖仓一体查询加速。基于数据湖创建异步物化视图的语法与基于内表创建完全相同,但需注意以下事项:

  • 物化视图刷新依赖数据湖的元数据缓存(如分区版本信息),而非直接从外部环境获取。因此,刷新完成后的数据与通过SelectDB查询数据湖的结果一致,但可能与通过其他引擎查询的结果存在差异,具体取决于缓存的刷新情况。

  • 如果Hive底层数据通过非SelectDB控制的外部流程(如Spark、HiveFlink作业)发生了变更,但没有改变元数据(如执行了INSERT OVERWRITE),可能导致物化视图认为与基表数据一致,但实际查询结果不一致。此时可以手动强制刷新物化视图来解决。

  • 基于Iceberg创建分区物化视图,仅支持Iceberg表分区列只有一列的情况,且有限度地支持分区演进功能(如时间类型的分区时间范围变化是支持的,但若分区字段发生变化则不支持,物化视图刷新会失败)。

  • 基于Hudi创建物化视图,无法感知基表数据是否发生了变化。只要刷新过物化视图(或部分分区),就会认为物化视图与基表同步。因此,基于Hudi创建的物化视图仅适用于手动按需刷新的场景。

物化刷新数据湖支持情况

不同类型的表和Catalog,物化视图刷新方式的支持情况如下:

表类型

Catalog类型

全量刷新

分区刷新

自动触发

内表

Internal

2.1支持

2.1支持

2.1.4支持

Hive

Hive

2.1支持

2.1支持

不支持

Iceberg

Iceberg

2.1支持

3.1支持

不支持

Paimon

Paimon

2.1支持

3.1支持

不支持

Hudi

Hudi

2.1支持

3.1支持

不支持

JDBC

JDBC

2.1支持

不支持

不支持

ES

ES

2.1支持

不支持

不支持

透明改写数据湖支持情况

目前,异步物化视图的透明改写功能支持以下类型的表和Catalog。其中,“实时感知基表数据”指物化视图使用的表数据发生变化时,物化视图能够实时感知,并在查询时使用最新的数据。

表类型

Catalog类型

透明改写支持

实时感知基表数据

内表

Internal

支持

支持

Hive

Hive

支持

3.1支持

Iceberg

Iceberg

支持

3.1支持

Paimon

Paimon

支持

3.1支持

Hudi

Hudi

支持

不支持

JDBC

JDBC

支持

不支持

ES

ES

支持

不支持

重要

物化视图使用外表时,默认不参与透明改写。如需开启外表透明改写,可执行SET materialized_view_rewrite_enable_contain_external_table = true。对于不支持感知数据变化的外表(如JDBC、ES),刷新物化视图时需显式指定REFRESH MATERIALIZED VIEW mvName COMPLETE,否则AUTO刷新可能导致物化视图数据不更新。

物化视图与OLAP内表的关系

异步物化视图的定义SQL对基表的数据模型没有限制,支持明细模型、主键模型(Merge-on-WriteMerge-on-Read)、聚合模型等。物化视图自身的底层实现基于Duplicate模型的OLAP表,理论上支持Duplicate模型的所有核心功能。但为了保证物化视图能够稳定、高效地执行数据刷新,对部分功能进行了以下限制:

  • 物化视图的分区基于基表自动创建和维护,用户不能对物化视图执行分区操作。

  • 由于物化视图背后有相关的作业(JOB)需要处理,不能使用DROP TABLERENAME TABLE命令操作物化视图,需使用物化视图自身的命令(如DROP MATERIALIZED VIEW)。

  • 物化视图的列数据类型由创建时的查询语句自动推导,不能被修改,否则可能导致刷新任务失败。

  • 物化视图特有的属性(property)需通过物化视图命令修改;其他公共属性可使用ALTER TABLE命令修改。

更多参考