关于异步物化视图分区刷新的疑问

我仔细看了关于异步物化视图的文档。文档中提到默认情况下只会对基表中数据发生变更的分区进行刷新。
是不是意味着,为了更好的性能,只查询数据发生变更的分区?
如果是,当基表按天分区,异步物化视图上卷按月分区,基表只写入当天数据。那异步物化视图就无法查询到基表整月的数据。
如果否,是不是每次刷新分区,都会查询全表数据?这样性能损耗太大了。

否 因为分区字段不一样 会查询全表数据

那如果秒级别的明细数据按天分区。 然后上卷做一个天维度也是按天分区的异步物化视图。
starrocks会做优化,只查询数据有变化的分区不?

我理解是会的 当前集群是什么版本 我可以确认下 或者您那边也可以自主验证下

当前版本是 2.5.12 cb07d99 。
我的下一个问题正是 如何确认是否只查询了数据变化的分区呢?

通过这个sql是可以看到物化视图的执行语句。
select * from information_schema.tasks order by CREATE_TIME desc limit 1;
但是我不清楚真正执行的时候就是按DEFINITION执行的,还是会填加额外的分区条件。

我验证了一下。
创建两个物化视图

-- mv1
CREATE MATERIALIZED VIEW mv1
DISTRIBUTED BY HASH(`event_uid`)
REFRESH ASYNC START('2023-10-26 10:50:00') EVERY (interval 1 MINUTE)
PARTITION BY dt
AS
SELECT
	date_trunc("DAY", event_dt) as dt,event_product_id , event_uid, sum(event_pay_fee) as event_pay_fee_day, now() as insert_time
FROM
        event_table
where event_dt >= '2023-10-20 00:00:00'	
group by date_trunc("DAY", event_dt),event_product_id , event_uid;

-- mv2
CREATE MATERIALIZED VIEW mv2
DISTRIBUTED BY HASH(`event_uid`)
REFRESH ASYNC START('2023-10-26 10:50:00') EVERY (interval 1 MINUTE)
AS
SELECT
	date_trunc("DAY", event_dt) as dt,event_product_id , event_uid, sum(event_pay_fee) as event_pay_fee_day, now() as insert_time
FROM
	event_table
where event_dt >= '2023-10-20 00:00:00'	
group by date_trunc("DAY", event_dt),event_product_id , event_uid;

mv1和mv2唯一得区别是mv2中没有分区表达式 PARTITION BY dt
event_table表只会写入当天得数据,不会写历史数据。 通过观察物化视图中的insert_time是否更新,来判断物化视图刷新时,是否查询了数据没有变化的历史分区。
结果mv1只有当天数据的insert_time会更新,历史分区的insert_time没有变化。
mv2中所有分区的insert_time都更新了。

结论是starrocks通过分区表达式 PARTITION BY dt 来判断基表和异步物化视图的分区是否对齐。 如果分区对齐,则刷新分区时只查询数据变化的分区。

1赞

每隔10分钟会无脑刷一次全表?
根据观察,物化视图和基表分区对齐, starrocks会只查数据有变化的分区。
但是每隔10分钟,会无脑查一次全表。
这种设计让人怎么用? 基表数据量很大,全表查是无法接受的。

物化视图不PARTITION BY 肯定要刷全部全表的

关键是PARTITION BY了,也查了全表的数据。
在我的例子中mv1每隔十分钟会刷一次全表。

请问基表 event_table 是怎么分区的?

建表语句如下

create table event_table (
    `event_dt` DateTime ,
    `event_uid` int ,
    event_pk_enum TINYINT ,
    event_pk_hash BIGINT ,
    `event_product_id` String ,
    `event_event_type` String ,
    .....
    `event_update_time` datetime NULL
) ENGINE=olap
PRIMARY KEY (event_dt, event_uid, event_pk_enum, event_pk_hash)
PARTITION BY RANGE (event_dt) (
    START ("2019-12-01") END ("2024-01-01") EVERY (INTERVAL 1 day)
)
DISTRIBUTED BY HASH(`event_uid`) BUCKETS 6
PROPERTIES (
    "colocate_with" = "cg_xxx",
    "replication_num" = "2",
    "dynamic_partition.enable" = "true",
    "dynamic_partition.time_unit" = "DAY",
    "dynamic_partition.end" = "3",
    "dynamic_partition.prefix" = "p",
    "dynamic_partition.buckets" = "6",
    "enable_persistent_index" = "true"
);

这个问题有结果没?

分区刷新需要设置几个参数:

  • PARTITION BY:指定基表和MV的分区映射
  • Properties (‘partition_refresh_number’=‘1’) : 指定每次刷新一个分区

这种配置下,按天分区只会刷新单天的分区,适合 T+1场景,每次只会更新今天的数据,同时刷新今天的物化视图。