大表实时聚合为什么慢
ClickHouse 擅长在亿级明细上做实时聚合,但每次查询都全表扫描算一遍 count、sum、group by,在高并发报表场景下还是吃力。解法是预计算:数据写入时就提前算好聚合结果存起来,查询时直接读小结果集。物化视图就是实现预计算的核心工具。
- MergeTreeClickHouse 最核心的表引擎。
- 物化视图写入时触发、自动维护聚合结果。
- 主键/排序键决定数据的物理排序与稀疏索引。
- 分区裁剪扫描范围、提升性能。
MergeTree:ClickHouse 的地基
几乎所有 ClickHouse 表都建在 MergeTree 家族上。它按主键排序存数据、按分区组织、用稀疏索引加速。写入时先落多个小数据片,后台再异步合并(merge)成大文件,所以叫 MergeTree。理解它的排序、分区、稀疏索引,是用深 ClickHouse 的前提。
物化视图是怎么工作的
物化视图不是普通视图那种查询时才计算的假视图。它在数据写入原表时,自动执行一段聚合逻辑、把结果写进一张目标表。查询报表时直接查这张小结果表,而不是每次扫明细。它像一个随数据写入自动维护的汇总表。
-- 建一张按天+渠道的 PV 汇总物化视图
CREATE MATERIALIZED VIEW pv_by_day
ENGINE = SummingMergeTree
ORDER BY (day, channel) AS
SELECT toDate(ts) AS day, channel, count() AS pv
FROM events GROUP BY day, channel;
预聚合与增量更新
物化视图随写入增量更新,新数据进来只算这部分、合并到结果表,不用重算全量。配合 SummingMergeTree、AggregatingMergeTree 这类引擎,可以自动做累加、合并状态。查询时读的是已经聚合好的小表,速度提升几个数量级。
主键、排序键与分区设计
ClickHouse 的主键同时是排序键,决定数据按什么物理顺序存储。把高频过滤、分组的列放前面,稀疏索引才能快速定位。分区一般按天或月,查询带时间条件时能直接跳过无关分区。排错顺序、分区粒度过粗过细,都会让本该很快的查询变慢。
引擎家族怎么选
普通明细用 MergeTree;要预聚合用 Summing/Aggregating;要去重用 ReplacingMergeTree;更新删除频繁用 Replacing 配合版本列。引擎选错,要么数据冗余要么更新代价大。选型的核心是先想清楚查询模式,再倒推用哪种引擎。
和实时分析文章的分工
前面那篇实时分析讲的是列式存储怎么让单次聚合飞快,是能力的底子;这篇讲的是在高并发报表下怎么用物化视图把查询结果提前算好,是工程优化。一个是"算得快",一个是"不用每次都算",两者搭配才是生产级的 ClickHouse 用法。
落地清单
- 高频报表用物化视图预聚合,别每次扫明细。
- 主键排序列要匹配高频过滤与分组。
- 分区按时间,控制扫描范围。
- 按查询模式选 Summing/Replacing 等引擎。
- 监控 merge 延迟与物化视图写入是否积压。