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

Posted

技术标签:

【中文标题】我可以在 AggregatingMergeTree 中插入聚合状态而不通过物化视图吗【英文标题】:Can I insert an aggregation state in an AggregatingMergeTree without going through a materialized view 【发布时间】:2021-09-06 23:57:10 【问题描述】:

我使用 AggregatingMergeTree 已经有一段时间了,通过物化视图填充它们,该视图从原始数据表生成聚合状态。这很好用。

我想知道是否有一种方法可以从我收到的数组中生成聚合状态,而无需通过每个数据点包含一行的表。 示例:

我发现我可以通过这种方式从数组中生成聚合状态:

SELECT countState([1,2,3,4,5])
SELECT uniqState(['user1', 'user2', 'user3'])
# Does not work with quantiles

虽然我没有设法将它们直接插入聚合合并树中。 示例:

CREATE TABLE state_test_agg(
    id UInt64,
    count_state AggregateFunction(count, UInt32),
    uniq_state AggregateFunction(uniq, String)
)
ENGINE = AggregatingMergeTree()
ORDER BY (id)

INSERT INTO state_test_agg (id, count_state, uniq_state) 
VALUES (1, countState([1,2,3,4]), uniqState(['a', 'b', 'b']))


Code: 184. DB::Exception: Aggregate function countState([1, 2, 3, 4]) is found in wrong place in query

如果我首先将存储桶(数组)存储在一个表中并尝试将它们移动到我得到的聚合合并树中

CREATE TABLE state_test_raw(
    id UInt64,
    count_bucket Array(UInt64),
    uniq_bucket Array(String)
)
ENGINE MergeTree
ORDER BY id

INSERT INTO state_test_raw (
    id, 
    count_bucket, 
    uniq_bucket)
VALUES
(1, [1,2,3,4,5,5], ['a', 'b', 'c'])

-- so far so good

INSERT INTO state_test_agg 
VALUES (id, count_state, uniq_state) 
SELECT 
    id, 
    countState(count_bucket) as count_state,  
    uniqState(uniq_bucket) as uniq_state 
FROM state_test_raw
GROUP BY id

Code: 47. DB::Exception: Missing columns: 'id' while processing query: 'id', required columns: 'id', source columns: '_dummy'

尚不清楚,但我认为这是一个问题,因为 Clickhouse 无法知道 id 列是否唯一。

有没有办法插入从数组生成的聚合状态而不是通过物化视图?

场景: 我想记录指标并在其上建立汇总表。简单的方法是将每个数据点存储为 MergeTree 中的一行,然后创建一个物化视图,通过填充聚合合并树来生成汇总。 示例:

timestamp, response_time, 200
timestamp2, response_time, 205
...

虽然这些数据点已经在源(因此是数组)中存储。

time_bucket_1, response_time, [200, 205]

我可以扩展它们并为每个数据点写入一行,但似乎我可以通过跳过该步骤并尝试直接从存储桶生成聚合状态来节省 Clickhouse 的存储和带宽,以及实现步骤使用的内存

谢谢。 菲利波

【问题讨论】:

clickhouse.tech/docs/en/sql-reference/table-functions/input 【参考方案1】:

考虑使用arrayReduce 将项目数组转换为聚合状态:

WITH
    arrayReduce('countState', [1, 2, 3, 4, 5]) AS state_1,
    arrayReduce('uniqState', ['user1', 'user2', 'user3', 'user1']) AS state_2
SELECT
    countMerge(state_1) AS merge_1,
    uniqMerge(state_2) AS merge_2

/*
┌─merge_1─┬─merge_2─┐
│       5 │       3 │
└─────────┴─────────┘
*/

INSERT INTO state_test_agg (id, count_state, uniq_state) 
VALUES 
  (1, 
   arrayReduce('countState', [toUInt32(1),2,3,4]), 
   arrayReduce('uniqState', ['a', 'b', 'b'])),
  (1, 
   arrayReduce('countState', [toUInt32(5),5]), 
   arrayReduce('uniqState', ['a', 'b', 'b','c']));
SELECT
    id,
    countMerge(count_state) AS c,
    uniqMerge(uniq_state) AS u
FROM state_test_agg
GROUP BY id

/*
┌─id─┬─c─┬─u─┐
│  1 │ 6 │ 3 │
└────┴───┴───┘
*/

【讨论】:

以上是关于我可以在 AggregatingMergeTree 中插入聚合状态而不通过物化视图吗的主要内容,如果未能解决你的问题,请参考以下文章

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

如何在 clickhouse 中使用 groupBitmapAnd 和 AggregatingMergeTree 引擎?

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

用户标签数据在ClickHouse的存储与使用

我可以将 UIImage 作为文本放在 textview 中,以便我可以在 ios 中将它们作为文本删除

我可以创建一个学生,但它不会保存在 mysql 表上。我收到一个控制台错误,我可以弄清楚它是啥[关闭]