具有 AggregatingMergeTree 引擎的物化视图删除条目而不是聚合

Posted

技术标签:

【中文标题】具有 AggregatingMergeTree 引擎的物化视图删除条目而不是聚合【英文标题】:Materialized view with AggregatingMergeTree engine removes entries instead of aggregation 【发布时间】:2021-11-05 17:05:23 【问题描述】:

假设我有下表

CREATE TABLE trades (
  `ts` DateTime64(9, 'UTC'), 
  `volume` Decimal(40, 20),
  `market` String
) ENGINE = MergeTree ORDER BY (market, ts)

以及它上面的物化视图

CREATE MATERIALIZED VIEW trades_per_hour 
ENGINE = AggregatingMergeTree()
ORDER BY (market, ts_1h)
AS (
    SELECT sum(volume) as volume, ts_1h, market
    FROM trades 
    GROUP BY market, toStartOfHour(ts) as ts_1h
)

我在那里插入了几条记录:

INSERT INTO trades (*) VALUES ('2021-01-01 01:08:00', '1.5', 'EUR')
INSERT INTO trades (*) VALUES ('2021-01-01 01:09:00', '3.7', 'EUR')

所以表格看起来像

┌────────────────────────────ts─┬─────────────────volume─┬─market─┐
│ 2021-01-01 01:08:00.000000000 │ 1.50000000000000000000 │ EUR    │
└───────────────────────────────┴────────────────────────┴────────┘
┌────────────────────────────ts─┬─────────────────volume─┬─market─┐
│ 2021-01-01 01:09:00.000000000 │ 3.70000000000000000000 │ EUR    │
└───────────────────────────────┴────────────────────────┴────────┘

现在,没有分组依据的物化视图显示两行(我猜这是预期的):

SELECT * FROM trades_per_hour;

┌─────────────────volume─┬───────────────ts_1h─┬─market─┐
│ 3.70000000000000000000 │ 2021-01-01 01:00:00 │ EUR    │
└────────────────────────┴─────────────────────┴────────┘
┌─────────────────volume─┬───────────────ts_1h─┬─market─┐
│ 1.50000000000000000000 │ 2021-01-01 01:00:00 │ EUR    │
└────────────────────────┴─────────────────────┴────────┘

如果用group子句查询,则显示:

SELECT sum(volume), ts_1h FROM trades_per_hour GROUP BY ts_1h;

┌────────────sum(volume)─┬───────────────ts_1h─┐
│ 5.20000000000000000000 │ 2021-01-01 01:00:00 │
└────────────────────────┴─────────────────────┘

如果我这样做了

OPTIMIZE TABLE trades_per_hour;

我只剩下一行了(我猜是因为重复数据删除?):

┌─────────────────volume─┬───────────────ts_1h─┬─market─┐
│ 1.50000000000000000000 │ 2021-01-01 01:00:00 │ EUR    │
└────────────────────────┴─────────────────────┴────────┘

所以卷 3.7 的行刚刚被删除。

我真正期待的是

┌─────────────────volume─┬───────────────ts_1h─┬─market─┐
│ 5.20000000000000000000 │ 2021-01-01 01:00:00 │ EUR    │
└────────────────────────┴─────────────────────┴────────┘

所以每个 ts_1h + 市场的“重复”实际上是聚合在一起的。

我想问一下我在表格和/或物化视图定义中做错了什么。

非常感谢任何帮助。 干杯。

【问题讨论】:

【参考方案1】:

需要使用AggregateFunction/SimpleAggregateFunction:

CREATE MATERIALIZED VIEW trades_per_hour 
(
  ts_1h DateTime64(9, 'UTC'),
  volume SimpleAggregateFunction(sum, Decimal(40, 20)),
  market String
)
ENGINE = AggregatingMergeTree()
PARTITION BY toYYYYMM(ts_1h)
ORDER BY (market, ts_1h)
AS 
SELECT toStartOfHour(ts) as ts_1h, sum(volume) as volume, market
FROM trades 
GROUP BY market, ts_1h

【讨论】:

非常感谢,弗拉基米尔。不知道我可以预先定义 MV 模式并给它一个关于聚合函数的提示。效果很好!

以上是关于具有 AggregatingMergeTree 引擎的物化视图删除条目而不是聚合的主要内容,如果未能解决你的问题,请参考以下文章

大数据ClickHouse:MergeTree系列表引擎之AggregatingMergeTree

我可以在 AggregatingMergeTree 中插入聚合状态而不通过物化视图吗

如何处理 Clickhouse 的 AggregatingMergeTree 物化视图中的嵌套字段?

具有多索引列的 Pandas groupby

加入数据框 - 一个具有多索引列,另一个没有

具有多索引的 Pandas 样式对象