基于本文回答
0
评论

讲讲 Doris 的物化视图(Materialized View)

Apache Doris 的物化视图(Materialized View,简称 MV)是其核心的查询加速技术之一。它的核心思想是“空间换时间”——通过预先计算好复杂的聚合操作、多表 Join,并将结果物理存储下来,当用户提交查询时,系统能够直接复用这些预计算的数据,从而实现毫秒级响应。

随着 Doris 版本的演进,物化视图经历了重大的架构升级。要深刻理解 Doris 的物化视图,必须将其分为两类来看:同步单表物化视图(早期引入)和 异步多表物化视图(Doris 2.0 引入,2.1 版本成熟)。

下面我将为你详细梳理 Doris 物化视图的方方面面。


一、 核心概念与两类物化视图

在 Doris 中,根据刷新机制和支持的查询复杂度,物化视图分为两类:

1. 同步单表物化视图(Synchronous Single-Table MV)

这是 Doris 早期就支持的特性(与 Rollup 机制类似但更灵活)。

  • 强一致性:当数据写入原表(Base Table)时,会同步写入物化视图。这意味着查询物化视图的数据永远是最新的,没有延迟。
  • 局限性:只能基于单表创建;只支持简单的聚合函数(如 SUM, MIN, MAX, COUNT, BITMAP_UNION, HLL_UNION 等);不支持 Join 等复杂操作。
  • 适用场景:单表的维度聚合分析(例如将秒级明细数据预聚合为小时级、天级数据),且对数据新鲜度要求极高(必须做到写可见即读可见)。

2. 异步多表物化视图(Asynchronous Multi-Table MV)

这是 Doris 在 v2.0/v2.1 引入的重量级特性,依赖全新的 Nereids 优化器

  • 支持复杂查询:支持多表 Join、复杂聚合、CTE、子查询、窗口函数等几乎所有复杂 SQL。
  • 异步刷新:数据更新不是实时的,而是通过定时任务或手动触发来刷新。
  • 分区刷新:支持按分区增量刷新,只刷新数据发生变动的分区,极大降低了刷新代价。
  • 适用场景:替换传统数仓中的 ETL 流水线(直接用 MV 建模);加速复杂的报表看板(如包含多表 Join 且计算量巨大的查询)。

二、 最强魔法:透明智能改写(Transparent Rewrite)

无论是同步还是异步物化视图,Doris 最强大的地方在于它的透明改写能力

在传统数据库中,如果你建了物化视图,往往需要修改 BI 工具或前端的 SQL,让它直接 SELECT * FROM mv_table
但在 Doris 中,你不需要修改任何业务 SQL

  1. 用户依然向 Doris 发送查询原始表(Base Table)的 SQL。
  2. Doris 的 Nereids 优化器 会在后台进行代价估算。
  3. 如果优化器发现存在一个物化视图能够满足查询结果,并且扫描物化视图的代价更低,它就会自动将查询路由到物化视图上

你可以通过 EXPLAIN your_sql 命令,查看执行计划中的 MaterializedViewRewriteSuccessAndChose 字段,确认是否命中了物化视图。


三、 异步多表物化视图的进阶特性(Doris 2.1+)

因为单表物化视图比较简单,目前的最佳实践主要集中在异步多表物化视图上。它有几个非常亮眼的特性:

1. 灵活的刷新策略

  • 全量刷新:每次刷新重新计算所有数据(适合数据量不大的维表 Join)。
  • 分区增量刷新(Partition Refresh):如果基表是分区表(例如按天分区),物化视图也可以按天分区。当某一天的数据发生变化时,Doris 只会重新计算并覆盖这一天的数据,其他历史分区不动。这对于 T+1 或 H+1 的大数据分析极其重要。

2. 自动/手动触发

你可以设置物化视图自动定时刷新:

sql
CREATE MATERIALIZED VIEW async_mv
BUILD DEFERRED -- 延迟构建
REFRESH AUTO ON SCHEDULE EVERY 1 HOUR -- 每小时自动刷新
AS 
SELECT a.id, b.name, SUM(a.amount) 
FROM table_a a 
JOIN table_b b ON a.id = b.id 
GROUP BY a.id, b.name;

3. 外表物化视图(Data Lake 加速)

Doris 的物化视图不仅可以基于 Doris 内部表创建,还可以基于 Hive、Iceberg、Hudi 等外部 Catalog 里的表创建!
你可以将外部数据湖里的慢查询预计算并物化到 Doris 内部,实现数据湖的极大加速。


四、 两类物化视图的对比总结

特性 同步单表物化视图 异步多表物化视图 (v2.0+)
表数量 仅限单表 支持多表 Join
查询支持 简单聚合计算 任意复杂 SQL(含 CTE、窗口函数等)
数据一致性 强一致,原子生效,无延迟 最终一致,存在延迟(取决于刷新频率)
刷新机制 随导入同步写入,系统自动管理 异步定时或手动触发,支持分区增量刷新
透明改写 支持,基于规则的匹配 支持,基于 Nereids 优化器,能力极强
主要应用 单表高频指标预聚合、点查加速 数仓分层建模、多表关联报表加速、数据湖加速

五、 最佳实践与避坑指南

  1. 按需创建,不要滥用:物化视图会占用存储空间,且同步 MV 会增加写入延迟,异步 MV 会消耗后台计算资源。只为那些高频且极其耗时的查询创建物化视图。
  2. 善用增量/分区刷新:对于事实表关联的异步物化视图,一定要配置分区(Partition by)。否则每次刷新都是全量计算,资源消耗巨大且极易失败。
  3. 大宽表 VS 多表物化视图:过去为了加速,常常在 Flink/Spark 预先打成大宽表写入 Doris。现在有了异步多表物化视图,可以将多表直接同步到 Doris,利用 Doris 内部的 MV 代替外部 ETL 进行“宽表化”建模,降低架构复杂度。
  4. 排查未命中原因:如果发现查询没有变快,使用 EXPLAIN 查看原因。常见未命中的原因包括:MV 正在刷新中不可用、过滤条件超出了 MV 包含的范围、聚合维度不匹配等。

总结

Doris 的物化视图已经从早期简单的“同步预聚合索引”,进化成了现代 OLAP 引擎中强大的“自动透明加速器”“数仓建模工具”。熟练掌握特别是 Nereids 驱动的多表异步物化视图,是榨干 Doris 性能、实现复杂报表秒出、精简大数据架构的关键所在。

右滑查看面试常问