使用AggregatingMergeTree引擎的Materialized view未聚合反而删除条目问题
问题根源
你使用AggregatingMergeTree引擎时没有定义非排序键的聚合规则:AggregatingMergeTree在合并相同ORDER BY键(即你定义的(market, ts_1h))的行时,需要你明确指定非排序字段的聚合逻辑。你当前把volume定义为普通Decimal类型,引擎无法识别该字段需要做求和聚合,合并时只会随机保留其中一行的数值,这就是OPTIMIZE操作后仅剩下1.5的原因。
你之前直接GROUP BY能得到正确结果,是因为合并操作执行前所有分片的行都还存在,手动求和可以得到正确值,但合并触发后重复排序键的行会被直接清理。
解决方案
方案一:使用SummingMergeTree(更适配当前简单求和场景)
SummingMergeTree是专门为求和聚合场景设计的引擎,会自动对相同排序键的数值字段做求和合并,使用更简单,完全符合你的需求:
CREATE MATERIALIZED VIEW trades_per_hour ENGINE = SummingMergeTree() ORDER BY (market, ts_1h) AS ( SELECT sum(volume) as volume, toStartOfHour(ts) as ts_1h, market FROM trades GROUP BY market, ts_1h )
后续你直接执行SELECT * FROM trades_per_hour就能得到合并后的聚合结果,不需要额外加GROUP BY逻辑,OPTIMIZE后也会自动合并为volume=5.2的单行数据。
方案二:使用AggregatingMergeTree(适配更复杂的多聚合场景)
如果你后续需要添加更多聚合逻辑(比如计数、求最大最小值等),可以继续使用AggregatingMergeTree,但需要修改字段类型和聚合函数:
- 物化视图定义改为使用
sumState定义聚合状态字段:
CREATE MATERIALIZED VIEW trades_per_hour ENGINE = AggregatingMergeTree() ORDER BY (market, ts_1h) AS ( SELECT sumState(volume) as volume, toStartOfHour(ts) as ts_1h, market FROM trades GROUP BY market, ts_1h )
- 查询时使用
sumMerge函数触发聚合计算,需配合GROUP BY使用:
SELECT sumMerge(volume) as volume, ts_1h, market FROM trades_per_hour GROUP BY market, ts_1h
内容的提问来源于stack exchange,提问作者silverthorne
相关产品推荐
相关产品推荐

