Skip to main content
该引擎继承自 MergeTree,并修改了数据分区片段合并的逻辑。ClickHouse 会将所有具有相同主键 (更准确地说,具有相同排序键) 的行合并为一行 (在单个数据分区片段内) ,该行存储聚合函数状态的组合。 你可以将 AggregatingMergeTree 表用于增量数据聚合,也可用于聚合 materialized view。 你可以在下面的视频中查看如何使用 AggregatingMergeTree 和聚合函数的示例:
该引擎会处理以下类型的所有列: 如果 AggregatingMergeTree 能将行数减少几个数量级,那么它就是合适的选择。

创建表

有关请求参数的说明,请参阅请求描述 查询子句 创建 AggregatingMergeTree 表时,所需的子句与创建 MergeTree 表时相同。

SELECT 和 INSERT

要插入数据,请使用带有聚合 -State- 函数的 INSERT SELECT 查询。 从 AggregatingMergeTree 表中查询数据时,请使用 GROUP BY 子句,并使用与插入数据时相同的聚合函数,但要加上 -Merge 后缀。 SELECT 查询结果中,AggregateFunction 类型的值在所有 ClickHouse 输出格式中都采用特定于实现的二进制表示。例如,如果你使用 SELECT 查询将数据转储为 TabSeparated 格式,就可以再通过 INSERT 查询将该转储重新加载。

aggregated materialized view 示例

以下示例假设您已有一个名为 test 的数据库。如果该数据库尚不存在,请使用以下命令创建:
现在创建包含原始数据的表 test.visits
接下来,您需要创建一个 AggregatingMergeTree 表,用于存储 AggregationFunction,以跟踪总访问次数和独立用户数量。 创建一个 AggregatingMergeTree materialized view,监听 test.visits 表,并使用 AggregateFunction 类型:
创建一个 materialized view,将数据从 test.visits 填充至 test.agg_visits
将数据插入 test.visits 表:
数据已写入 test.visitstest.agg_visits 两张表。 要获取聚合数据,请对 materialized view test.visits_mv 执行如下查询,例如 SELECT ... GROUP BY ...
再向 test.visits 中添加几条记录,但这次为其中一条记录使用不同的时间戳:
再次运行 SELECT 查询,将返回以下输出:
在某些情况下,您可能希望避免在写入时对行进行预聚合,将聚合开销从写入时推迟到合并时。通常,为避免报错,需要在 materialized view 定义的 GROUP BY 子句中包含所有不参与聚合的列。不过,您可以配合设置 optimize_on_insert = 0 (默认为开启状态) ,使用 initializeAggregation 函数来实现这一目的。此时无需再使用 GROUP BY
使用 initializeAggregation 时,会为每一行分别创建一个聚合状态,而不会进行分组。 每个源行都会在 materialized view 中生成一行,实际的聚合会在后续 AggregatingMergeTree 合并 parts 时发生。只有在 optimize_on_insert = 0 时才是如此。

Tuple 元素聚合

启用 allow_tuple_element_aggregation 设置后,Tuple 列会被递归展平,使每个叶子元素都能独立参与聚合。这意味着,Tuple 中的 AggregateFunctionSimpleAggregateFunction 子列会按照各自的函数进行聚合,就像它们是顶层列一样。 排序键中的 Tuple 子列不参与聚合。非聚合子列会被视为普通列 (保留其第一个值) 。
此设置不可变,必须在创建表时指定。
total_visits 通过 sum 聚合 (100 + 200 = 300) ,而 unique_users 则通过 max 聚合 (max(5, 8) = 8) 。
最后修改于 2026年7月23日