为什么 maxMerge() 给出的结果与 sumMerge() 的 max() 不同?
Why maxMerge() gives different results than max() of sumMerge()?
重点是获取每个周期的峰值(例如 5m 峰值)以获取累积值。因此需要对每个周期求和,然后可以在这些总和中找到峰值(最大值)。 (select max(v) from (select sum(v) from t group by a1, a2)
)
我有一个基地 table t
.
数据插入t
,考虑两个属性(时间t1
和一些字符串a2
)和一个数值
值会累加,因此需要将其相加得到一定时期内的总交易量。插入的行示例:
t1 | a2 | v
----------------
date1 | b | 1
date2 | c | 20
我正在使用 MV 来计算 sumState()
,然后使用 sumMerge()
然后 max()
.
从中得到峰值
我只需要最大值,所以我想知道我可以直接使用 maxState()
。
所以这就是我现在所做的:我使用 MV 计算 5m 总和并从中读取 max()
CREATE TABLE IF NOT EXISTS sums_table ON CLUSTER '{cluster}' (
t1 DateTime,
a2 String,
v AggregateFunction(sum, UInt32)
)
ENGINE = ReplicatedAggregatingMergeTree(
'...',
'{replica}'
)
PARTITION BY toDate(t1)
ORDER BY (a2, t1)
PRIMARY KEY (a2);
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_a
ON CLUSTER '{cluster}'
TO sums_table
AS
SELECT toStartOfFiveMinute(t1) AS t1, a2,
sumState(toUInt32(v)) AS v
FROM t
GROUP BY t1, a2
据此,我可以使用
读取 a2
的最大 5m 总和
SELECT
a2,
max(sum) AS max
FROM (
SELECT
t1,
a2,
sumMerge(v) AS sum
FROM sums_table
WHERE t1 BETWEEN :fromDateTime AND :toDateTime
GROUP BY t1, a2
)
GROUP BY a2
ORDER BY max DESC
效果很好。
所以我想使用 maxState
和 maxMerge()
:
来达到同样的效果
CREATE TABLE IF NOT EXISTS max_table ON CLUSTER '{cluster}' (
t1 DateTime,
a2 String,
max_v AggregateFunction(max, UInt32)
)
ENGINE = ReplicatedAggregatingMergeTree(
'...',
'{replica}'
)
PARTITION BY toDate(t1)
ORDER BY (a2, t1)
PRIMARY KEY (a2)
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_b
ON CLUSTER '{cluster}'
TO max_table
AS
SELECT
t1,
a2
maxState(v) AS max_v
FROM (
SELECT
toStartOfFiveMinute(t1) AS t1,
a2,
toUInt32(sum(v)) AS v
FROM t
GROUP BY t1, a2
)
GROUP BY t1, a2
我想如果我得到每个时间 (t1) 和 a2 的最大值,然后 select 每个 a2 的最大值,我会得到每个 a2 的最大值,但我得到与上述总和的最大值相比,使用此查询的最大值完全不同。
SELECT
a2,
max(max) AS max
FROM (
SELECT
t1,
a2,
maxMerge(v) AS max
FROM max_table
WHERE t1 BETWEEN :fromDateTime AND :toDateTime
GROUP BY t1, a2
) maxs_per_time_and_a2
GROUP BY a2
我做错了什么?我是不是看错了MV?是否可以将 maxState
和 maxMerge
用于 2+ 个属性来计算较长时间段内的最大值,比方说年份?
SELECT
t1,
a2
maxState(v) AS max_v
FROM (
SELECT
toStartOfFiveMinute(t1) AS t1,
a2,
toUInt32(sum(v)) AS v
FROM t
GROUP BY t1, a2
)
GROUP BY t1, a2
这是不正确的。而且不可能。
因为 MV 是插入触发器。它从不读取 REAL table t
。
您正在从插入缓冲区中的行总和中获取最大值。
如果使用 v=10
插入 1 行。你会得到 max_v = 10。MatView 不“知道”之前的插入已经添加了一些行,它们的总和没有被考虑在内。
重点是获取每个周期的峰值(例如 5m 峰值)以获取累积值。因此需要对每个周期求和,然后可以在这些总和中找到峰值(最大值)。 (select max(v) from (select sum(v) from t group by a1, a2)
)
我有一个基地 table t
.
数据插入t
,考虑两个属性(时间t1
和一些字符串a2
)和一个数值
值会累加,因此需要将其相加得到一定时期内的总交易量。插入的行示例:
t1 | a2 | v
----------------
date1 | b | 1
date2 | c | 20
我正在使用 MV 来计算 sumState()
,然后使用 sumMerge()
然后 max()
.
我只需要最大值,所以我想知道我可以直接使用 maxState()
。
所以这就是我现在所做的:我使用 MV 计算 5m 总和并从中读取 max()
CREATE TABLE IF NOT EXISTS sums_table ON CLUSTER '{cluster}' (
t1 DateTime,
a2 String,
v AggregateFunction(sum, UInt32)
)
ENGINE = ReplicatedAggregatingMergeTree(
'...',
'{replica}'
)
PARTITION BY toDate(t1)
ORDER BY (a2, t1)
PRIMARY KEY (a2);
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_a
ON CLUSTER '{cluster}'
TO sums_table
AS
SELECT toStartOfFiveMinute(t1) AS t1, a2,
sumState(toUInt32(v)) AS v
FROM t
GROUP BY t1, a2
据此,我可以使用
读取a2
的最大 5m 总和
SELECT
a2,
max(sum) AS max
FROM (
SELECT
t1,
a2,
sumMerge(v) AS sum
FROM sums_table
WHERE t1 BETWEEN :fromDateTime AND :toDateTime
GROUP BY t1, a2
)
GROUP BY a2
ORDER BY max DESC
效果很好。
所以我想使用 maxState
和 maxMerge()
:
CREATE TABLE IF NOT EXISTS max_table ON CLUSTER '{cluster}' (
t1 DateTime,
a2 String,
max_v AggregateFunction(max, UInt32)
)
ENGINE = ReplicatedAggregatingMergeTree(
'...',
'{replica}'
)
PARTITION BY toDate(t1)
ORDER BY (a2, t1)
PRIMARY KEY (a2)
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_b
ON CLUSTER '{cluster}'
TO max_table
AS
SELECT
t1,
a2
maxState(v) AS max_v
FROM (
SELECT
toStartOfFiveMinute(t1) AS t1,
a2,
toUInt32(sum(v)) AS v
FROM t
GROUP BY t1, a2
)
GROUP BY t1, a2
我想如果我得到每个时间 (t1) 和 a2 的最大值,然后 select 每个 a2 的最大值,我会得到每个 a2 的最大值,但我得到与上述总和的最大值相比,使用此查询的最大值完全不同。
SELECT
a2,
max(max) AS max
FROM (
SELECT
t1,
a2,
maxMerge(v) AS max
FROM max_table
WHERE t1 BETWEEN :fromDateTime AND :toDateTime
GROUP BY t1, a2
) maxs_per_time_and_a2
GROUP BY a2
我做错了什么?我是不是看错了MV?是否可以将 maxState
和 maxMerge
用于 2+ 个属性来计算较长时间段内的最大值,比方说年份?
SELECT
t1,
a2
maxState(v) AS max_v
FROM (
SELECT
toStartOfFiveMinute(t1) AS t1,
a2,
toUInt32(sum(v)) AS v
FROM t
GROUP BY t1, a2
)
GROUP BY t1, a2
这是不正确的。而且不可能。
因为 MV 是插入触发器。它从不读取 REAL table t
。
您正在从插入缓冲区中的行总和中获取最大值。
如果使用 v=10
插入 1 行。你会得到 max_v = 10。MatView 不“知道”之前的插入已经添加了一些行,它们的总和没有被考虑在内。