clickhouse AggregatingMergeTree

聚合

对比于传统的数据库如mysql ,要使用聚合的时候,全量算一遍这种思路。

clickhouse 的解决方案更加智慧。

它用另外一张表去存储聚合结果,然后通过数据变动实时(准实时)写入结果表,来达到聚合的目的。

如果对实时性要求不高的场景是非常适合的

先看下例子:

建表

先建立明细表

sql 复制代码
create table learning.money_detail(
   id UInt8,
   user_time Date,
   money UInt64
) engine = MergeTree()
partition by toDate(user_time)
order by id;

插入数据

sql 复制代码
insert into learning.money_detail values(1,'2026-05-04',10);
insert into learning.money_detail values(1,'2026-05-04',10);
insert into learning.money_detail values(2,'2026-05-05',15);
insert into learning.money_detail values(2,'2026-05-05',35);

聚合表

sql 复制代码
create table learning.money_agg(
   id UInt8,
   user_time Date,
   cnt AggregateFunction(count,UInt64),
   total_money AggregateFunction(sum,UInt64)
) engine = AggregatingMergeTree()
partition by toDate(user_time)
order by id;

执行同步sql

sql 复制代码
insert into learning.money_agg 
select id,user_time,countState(id),
sumState(money)
from learning.money_detail
group by id,user_time

查询

sql 复制代码
select id,user_time,countMerge(cnt),sumMerge(total_money) 
from learning.money_agg
group by id,user_time

注意

insert 聚合表的时候一定要 countState,sumState + group by

查询聚合表的时候一定是 countMerge,sumMerge+ group by

物化视图

刚才的操作是人工同步的,真正生产上不可能每次源表写入都sql同步一次

正确的做法是写一个物化视图

sql 复制代码
create materialized view m_v_daily_agg to learning.money_agg as 
select id,user_time,countState(id) as cnt,
sumState(money) as total_money
from learning.money_detail
group by id,user_time

其中 materialized view m_v_daily_agg to learning.money_agg 是指定目标表,

select id,user_time,countState(id) as cnt,

sumState(money) as total_money

from learning.money_detail

group by id,user_time

就是写字段映射

执行物化视图后再插入源表数据就可以同步聚合表了 。

注意

物化视图创建前的数据不会被同步,如果需要同步需要

对比

对比于这段聚合sql

sql 复制代码
select id,user_time,count(money) as cnt,avg(money) as total_money 
from learning.money_detail group by id,user_time ;

它也能查出聚合,但是是它是传统的查法,每次都把全量数据做了一次聚合,遇到数据量大的场景,分钟级响应甚至卡死

然而clickhouse的 AggregatingMergeTree 做法更聪明,它在源数据每次插入的时候都做了一次增量聚合计算。计算量小,查询的时候只要去聚合表中查询结果就好,完全绕过了大数据量带来的相应慢问题。

附上 AggregatingMergeTree 的时序图

AggregatingMergeTree 的问题

它解决了大数据的聚合慢问题,但是它不是实时的,它的刷盘会有一定的延时,在那种要求实时响应的场景会出现数据不准的情况(还未刷盘)

所以并不适合精确要求高的场景

而且相比之前的源表操作,写入的整体压力肯定会增加

SummingMergeTree

如果你的业务逻辑只有求和(sum)和计数(count),不需要去重(uniq)或其他复杂聚合,用它更简单高效

相关推荐
zhoupenghui16813 天前
ClickHouse merge引擎详解以及应用
数据库·clickhouse·merge·mergetree
ClickHouseDB14 天前
ClickHouse 十年开源,今非昔比!
clickhouse·开源·apache
ClickHouseDB15 天前
ClickHouse 开源十年:数据分析领域的中流砥柱
clickhouse·数据分析·开源
java_logo19 天前
Docker Compose 部署 ClickHouse:快速搭建高性能列式数据库
数据库·clickhouse·docker·列式数据库·轩辕镜像·高性能数据库·clickhouse部署教程
ClickHouseDB20 天前
TPC-H 成本不到一分钱:ClickHouse Cloud 对比 Snowflake、Databricks、BigQuery 和 Redshift
clickhouse
隔壁阿布都23 天前
ClickHouse完整指南
服务器·数据库·clickhouse
数据库小学妹23 天前
MySQL做报表太慢?引入ClickHouse列式存储,同一个查询快240倍
mysql·clickhouse·列式存储·分析型数据库·向量化执行·olap数据库·mysql对比
ClickHouseDB1 个月前
推出 ClickHouse Cloud 中的多阶段分布式查询执行
分布式·clickhouse
weixin_307779131 个月前
Linux下ClickHouse数据仓库故障系统化诊断脚本
linux·运维·clickhouse·自动化·数据库开发
SelectDB技术团队1 个月前
Agent 场景动态 JSON 性能拆解:Apache Doris 比 ClickHouse 快 7 倍、比 Elasticsearch 快 2 倍
数据库·clickhouse·elasticsearch·json·apache·日志分析·apache doris