物化视图

一、什么是物化视图
和普通的视图不一样,物化视图不仅生成视图而且能存储数据,本质是一张MTMV的内表,创建一个定时任务将数据写入,它的表结构由SQL推导生成不支持修改
二、使用场景
实时报表查询、数据分层(ODS--->DWD--->DWS)、湖仓一体(物化外部数据源,加速查询)
三、分类
根据存储时效分为同步物化视图和异步物化视图,
3.1 同步:源表只能单表,实时刷新同步数据,
有以下几个致命伤:
不支持客户端直接查询,只能透明改写,
物化视图针对 Unique Key 数据模型时,只能改变列的顺序,不能起到聚合的作用
不支持having、limit等语法,仅适用于常见orderby groupby等
适合场景:
很少
3.2 异步:
源表可以是多表,最终一致性,按照刷新时效分为源表数据变化刷新、手动刷新、定时刷新两种方式,按照刷新数据分布分为全量刷新和增量分区刷新,只推荐小时级刷新
全量刷新就是重新运行一次SQL,增量分区刷新是指:源表可以是多个表,但必须在多个表当中指定某一张表的分区键当做物化异步视图的分区键,当刷新时,只重新计算源表某个分区数据,
1 源表数据变化刷新(物化视图无分区、源表无分区):
CREATE MATERIALIZED VIEW mv_1_1
BUILD IMMEDIATE
REFRESH COMPLETE
ON COMMIT
PROPERTIES ('replication_num' = '1')
AS
SELECT
l_linestatus,
to_date(o_orderdate) as date_alias,
o_shippriority
FROM
orders
LEFT JOIN lineitem ON l_orderkey = o_orderkey;
当 orders 或者 lineitem 表数据发生变化的时候,会自动触发物化视图的刷新。
2 源表数据变化刷新(物化视图有分区、源表无分区):
创建分区物化视图时,需要指定 PARTITION BY,对于分区字段引用的表达式,仅允许使用 date_trunc 函数和标识符,创建SQL如下:
CREATE MATERIALIZED VIEW mv_2_0
BUILD IMMEDIATE
REFRESH AUTO
ON MANUAL
PARTITION BY (order_date_month)
DISTRIBUTED BY RANDOM BUCKETS 2
AS
SELECT
l_linestatus,
date_trunc(o_orderdate, 'month') as order_date_month, ---关注这个date_trunc方法
o_shippriority
FROM
orders
LEFT JOIN lineitem ON l_orderkey = o_orderkey;
3 源表数据变化刷新(物化视图有分区、源表是分区表):创建语句和上面一样。
分为“使用基表的部分分区”和"使用基表的全部分区并上卷"
3.1 使用基表的部分分区:
代表物化视图只关注最近一天的数据。
若当前时间为 2024-03-28 xx:xx:xx,这样物化视图会仅有一个分区 [("2024-03-28"),("2024-03-29")]:
若时间又过了一天,当前时间为 2024-03-29 xx:xx:xx,t1则会新增一个分区 [("2024-03-29"),("2024-03-30")],
CREATE MATERIALIZED VIEW mv1
BUILD DEFERRED REFRESH AUTO ON MANUAL
partition by(k2)
DISTRIBUTED BY RANDOM BUCKETS 2
PROPERTIES (
'partition_sync_limit'='1',
'partition_sync_time_unit'='DAY'
)
AS
SELECT * FROM t1;
3.2 使用基表全部分区并上卷

CREATE MATERIALIZED VIEW mv_3
BUILD DEFERRED REFRESH AUTO ON MANUAL
partition by (date_trunc(k2,'month')) ---注意这里是按月来分区,这样就是上卷
DISTRIBUTED BY RANDOM BUCKETS 2
AS
SELECT * FROM t1;

四、回答
问:物化视图是如何判断需要刷新哪些分区的?
答:Doris 内部会计算物化视图和基表的分区对应关系,并且记录上次刷新成功后物化视图使用的基表分区版本。例如,物化视图 mv1 由基表 t1 和 t2 创建,并且依赖 t1 进行分区。
假设 mv1 的分区 p202003 对应基表 t1 的分区 p20200301 和 p20200302,那么刷新 p202003 之后,会记录分区 p20200301、p20200302,以及表 t2 的当前版本。
下次刷新时,会判断 p20200301、p20200302 以及 t2 的版本是否发生变化。如果其中之一发生了变化,就代表 p202003 需要刷新。
当然,如果业务上能接受 t2 的变化而不触发 mv1 的刷新,可以通过物化视图的属性excluded_trigger_tables来设置。

问:物化视图适合近实时场景吗?
答:不太适合。物化视图刷新的最小单位是分区,如果数据量较大会占用较多的资源,并且实时性不够。可以考虑使用同步物化视图或其他手段。

问:什么情况会导致物化视图的状态变更并且不可用?
答:不可用,指代的是“物化视图不能用于透明改写”的简称,而物化视图仍然可以直接查询。
对于全量物化视图,如果使用的基表数据发生变更或者发生 Schema Change,会导致物化视图不可用。
对于分区物化视图,基表数据变更会导致对应的分区不可用。而基表的 Schema Change 则会导致整个物化视图不可用。
目前,物化视图刷新失败也会导致其不可用。但后续会进行优化,即使刷新失败,已存在的物化视图仍然可用于透明改写。

posted @ 2025-12-08 09:47  秋水依然  阅读(17)  评论(0)    收藏  举报