异步物化视图(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、Hudi从3.1版本起支持分区增量刷新;JDBC和ES外表不支持分区增量刷新,刷新时需指定COMPLETE全量刷新。
物化视图本身的数据模型:物化视图本身只能是明细模型(Duplicate Key),不受基表数据模型限制。
集合操作与特殊语法限制:如果物化视图包含UNION ALL等集合操作、LIMIT、ORDER BY、CROSS JOIN,物化视图可以正常构建,但不能用于透明改写。
原理
MTMV(多表物化视图)
SelectDB的异步物化视图基于MTMV(Multi-Table Materialized View)框架实现。MTMV框架将物化视图的定义SQL(查询语句)与基表解耦,在后台异步执行刷新任务,将物化视图的数据更新为最新状态。每个物化视图都有独立的刷新任务(Job),由调度器管理执行。
刷新机制
异步物化视图的刷新过程如下:
刷新任务触发(手动/定时/ON COMMIT)。
系统检测基表数据自上次刷新后是否发生变化(仅支持内表和Hive外表)。
对于分区物化视图,仅刷新数据变化的分区,分区增量刷新;对于非分区物化视图,刷新全量数据。
刷新完成后,更新物化视图的版本信息和状态(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、Hive或Flink作业)发生了变更,但没有改变元数据(如执行了
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-Write和Merge-on-Read)、聚合模型等。物化视图自身的底层实现基于Duplicate模型的OLAP表,理论上支持Duplicate模型的所有核心功能。但为了保证物化视图能够稳定、高效地执行数据刷新,对部分功能进行了以下限制:
物化视图的分区基于基表自动创建和维护,用户不能对物化视图执行分区操作。
由于物化视图背后有相关的作业(JOB)需要处理,不能使用
DROP TABLE或RENAME TABLE命令操作物化视图,需使用物化视图自身的命令(如DROP MATERIALIZED VIEW)。物化视图的列数据类型由创建时的查询语句自动推导,不能被修改,否则可能导致刷新任务失败。
物化视图特有的属性(property)需通过物化视图命令修改;其他公共属性可使用
ALTER TABLE命令修改。
更多参考
创建、查询与维护异步物化视图,请参考创建、查询与维护异步物化视图。
最佳实践,请参考异步物化视图最佳实践。
常见问题,请参考异步物化视图常见问题。