ClickHouse 的物化视图是一种查询结果的持久化,它的存在是为了带来查询效率的提升。用户使用物化视图时跟普通的表没有太大区别,其实它就是一张逻辑表,也像是一张时刻在预计算的表,创建的过程它是用了一个特殊引擎,加上后来 as select,就是 create 一个 table as select 的写法。
普通视图:普通视图不保存数据,保存的仅是查询语句,查询的时候还是从原表读取数据,可以将普通视图理解为是个子查询。
物化视图:物化视图是把查询的结果根据相应的引擎存入到了磁盘或内存中,对数据重新进行了组织,你可以理解物化视图是完全的一张新表。
CREATE [MATERIALIZED] VIEW [IF NOT EXISTS] [db.]table_name [TO[db.]name]
[ENGINE = engine] [POPULATE] AS SELECT ...
使用create 创建一个物化视图,会创建一个隐藏的目标表来保存视图数据,也可以 TO 表名,保存到 一 张显式的表。没有加 TO 表名,表名默认就是 .inner.物化视图名;
创建 pm 性能数据表
性能表以 start_time 和 ne_name 为组合主键,day_id 为分区,ReplacingMergeTree 为合并引擎
CREATE TABLE default.test_01_pm
(
`insert_time` DateTime COMMENT '插入时间',
`start_time` String COMMENT '数据时间',
`ne_name` String COMMENT '网元名称',
`pm_01` String COMMENT 'pm_01',
`pm_02` String COMMENT 'pm_02',
`day_id` String COMMENT '天分区'
)
ENGINE = ReplacingMergeTree()
PARTITION BY (day_id)
PRIMARY KEY (start_time,ne_name)
ORDER BY (start_time,ne_name)
创建 cm 配置数据表
同上,但是 cm 配置数据主键是 ne_name
CREATE TABLE default.test_01_cm
(
`insert_time` DateTime COMMENT '插入时间',
`ne_name` String COMMENT '网元名称',
`cm_01` String COMMENT 'cm_01',
`cm_02` String COMMENT 'cm_02',
`day_id` String COMMENT '天分区'
)
ENGINE = ReplacingMergeTree()
PARTITION BY (day_id)
PRIMARY KEY ne_name
ORDER BY ne_name;
-- pm 性能数据
INSERT INTO table default.test_01_pm values(now(),'20240117080000','NE_01','100','200','2024-01-17');
INSERT INTO table default.test_01_pm values(now(),'20240117080000','NE_02','100','200','2024-01-17');
INSERT INTO table default.test_01_pm values(now(),'20240117080000','NE_03','100','200','2024-01-17');
INSERT INTO table default.test_01_pm values(now(),'20240117080000','NE_04','100','200','2024-01-17');
-- 模拟重复数据
INSERT INTO table default.test_01_pm values(now(),'20240117080000','NE_01','200','300','2024-01-17');
INSERT INTO table default.test_01_pm values(now(),'20240117080000','NE_01','500','600','2024-01-17');
-- cm 配置数据
INSERT INTO table default.test_01_cm values(now(),'NE_01','10','20','2024-01-17');
INSERT INTO table default.test_01_cm values(now(),'NE_02','10','20','2024-01-17');
INSERT INTO table default.test_01_cm values(now(),'NE_03','10','20','2024-01-17');
INSERT INTO table default.test_01_cm values(now(),'NE_04','10','20','2024-01-17');
pm 数据查询
select * from default.test_01_pm
cm 数据查询
select * from default.test_01_cm
创建物化视图将两个表关联起来
通过 ne_name 将 cm 配置表中的数据关联到 pm性能表中,达到扩充表字段目的。(特别注意:不建议添加 populate 关键字,原因在最下面)
create materialized view test_mv
engine ReplacingMergeTree()
partition by (day_id)
primary key(start_time,ne_name)
order by (start_time,ne_name)
populate
as
select
a.insert_time,
a.start_time,
a.ne_name,
a.pm_01,
a.pm_02,
b.cm_01,
b.cm_02,
a.day_id
from
`default`.test_01_pm a
left join test_01_cm b on a.ne_name = b.ne_name
物化视图数据查询
select * from default.test_mv
注意:
1、populate 参数不建议添加,这个参数会导致历史数据的计算,如果不添加此参数则物化视图创建之后,只对新增数据进行物化视图的计算。
2、不使用 populate 又想刷新历史数据,可以使用 insert into Table2(field1,field2,field3,...) select value1,value2,... from Table1 方式进行数据刷入。以下举例说明:
-- 将 2024年以来的数据重新刷入到物化视图中,物化视图使用了 ReplacingMergeTree 引擎可以根据主键合并,将最新的结果数据更新进去
insert into default.test_mv
select
a.insert_time,
a.start_time,
a.ne_name,
a.pm_01,
a.pm_02,
b.cm_01,
b.cm_02,
a.day_id
from
`default`.test_01_pm a
left join test_01_cm b on a.ne_name = b.ne_name
where a.start_time >= '202401010000'