首页/数据/NoSQL 速查/SummingMergeTree 预聚合
ClickHouse56 条

SummingMergeTree 预聚合

SummingMergeTree 在合并时把排序键相同的行中的数值列做求和,实现轻量级预聚合:写入明细行,查询直接读聚合结果,减少数据量。

NoSQL 速查数据更新于 2026-10-13

合并时求和是怎么工作的

SummingMergeTree 在后台合并 part 时,把排序键相同的行合并成一行,其中的数值列自动求和。写入侧仍然按明细行写,查询侧读到的通常已经是聚合后的结果,数据量随合并逐步收敛,起到轻量预聚合的作用。

它不是精确的预聚合

求和发生在合并阶段而不是写入阶段,合并时机由后台决定,所以查询可能读到尚未合并的重复键行。可靠用法是查询时再加一层 sum 加 group by,或者接受最终一致。另外它只适合可加性指标:平均值这类不可加指标要存分子与分母,或者改用 AggregatingMergeTree 保存聚合状态。

基本信息

引擎参数SummingMergeTree([columns]),不指定时对所有非排序键数值列求和
合并语义按排序键聚合,非求和列取任意一行值
读取兜底未合并数据仍有重复键,查询需 SUM 加 GROUP BY 或 FINAL
适用指标计数、金额等可加性指标
适用版本ClickHouse 各主流版本均支持

示例

示例
CREATE TABLE daily_sales
(
    d Date,
    shop_id UInt64,
    orders UInt64,
    amount Decimal(18, 2)
)
ENGINE = SummingMergeTree((orders, amount))
ORDER BY (d, shop_id);

INSERT INTO daily_sales VALUES (today(), 1, 1, 9.9), (today(), 1, 2, 19.8);

-- 查询时统一带上聚合,未合并的行也能得到正确结果
SELECT d, shop_id, sum(orders), sum(amount)
FROM daily_sales
GROUP BY d, shop_id;

典型使用场景

  • 明细直写:上游按事件写入,预聚合在合并阶段自动完成
  • 计数与金额汇总:按天、按门店统计可加指标
  • 降低存储:重复维度行的数值被合并,长期看行数明显减少
  • 实时看板:查询侧再加 sum 兜底,兼顾实时性与最终一致性
  • 结构迁移:从明细表切换到预聚合表时保持同一套查询写法

要素与注意

要素含义注意
排序键合并的聚合维度应选低频、稳定的维度列
求和列参与求和的数值列不写时对所有非排序键数值列求和
非求和列合并时取任意一行值不要依赖其取值做业务判断
FINAL查询时强制合并代价高,仅用于临时核对
它不维护中间聚合状态,适合可加性指标;平均值这类不可加指标应先存分子与分母,或者改用 AggregatingMergeTree 保存聚合状态再合并。
排序键里出现高基数列会让合并几乎无收益,因为每个键值都只有一行;键要选真正的聚合维度,行数才会收敛下来。

易错点

  • 排序键里出现高基数列会让合并几乎无收益,键要选聚合维度而不是唯一标识
  • 非求和列的值在合并后是不确定的,不要依赖它们做业务判断
  • 以为写入后就立刻完成聚合:合并由后台决定,查询必须自己聚合或接受最终一致
  • 把平均值这类不可加指标直接交给求和列,得到的数字没有业务意义

数据来源与参考

  • ClickHouse Docs: SummingMergeTree
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌