ClickHouse - SELECT 行数据太慢
ClickHouse - SELECT row of data is too slow
我们项目中出现以下问题,无法解决。
我们有大量的日志数据,我们从 MongoDB.
转到 ClickHouse
我们的table是这样创建的:
CREATE TABLE IF NOT EXISTS logs ON CLUSTER default (
raw String,
ts DateTime64(6) MATERIALIZED toDateTime64(JSONExtractString(raw, 'date_time'), 6),
device_id String MATERIALIZED JSONExtractString(raw, 'device_id'),
level Int8 MATERIALIZED JSONExtractInt(raw, 'level'),
context String MATERIALIZED JSONExtractString(raw, 'context'),
event String MATERIALIZED JSONExtractString(raw, 'event'),
event_code String MATERIALIZED JSONExtractInt(raw, 'event_code'),
data String MATERIALIZED JSONExtractRaw(raw, 'data'),
date Date DEFAULT toDate(ts),
week Date DEFAULT toMonday(ts)
)
ENGINE ReplicatedReplacingMergeTree()
ORDER BY (device_id, ts)
PARTITION BY week
我是运行这样的查询
SELECT device_id,toDateTime(ts),context,level,event,data
FROM logs
WHERE device_id = 'some_uuid'
ORDER BY ts DESC
LIMIT 10
OFFSET 0;
这是集合中 10 行的结果。 已用:6.23 秒
第二个没有顺序、限制和偏移量:
SELECT device_id,toDateTime(ts),context,level,event,data
FROM logs
WHERE device_id = 'some_uuid'
这是结果 耗时:7.994 秒。 每 500 行 130000+
太慢了。
似乎 CH 处理了 table 中的所有行。 CH有什么问题需要提高速度吗?
MongoDB 上的相同实现需要 200-500 毫秒 max
叶戈尔!当您提到“我们从 MongoDB 转到 ClickHouse”时,您的意思是您从 MongoDB 切换到 ClickHouse 来存储您的数据吗?或者您以某种方式连接到 ClickHouse,从 MongoDB 到您所指的 运行 查询?
我不确定你是如何摄取数据的,但让我们专注于阅读部分。
对于MergeTree家族,ClickHouse是分段写入数据的。因此,将时间戳作为 where 子句的一部分至关重要,这样 ClickHouse 就可以确定您要读取的部分并跳过大部分不需要的数据。否则,它将扫描所有数据。
我想这些查询会更快地进行扫描:
SELECT device_id,toDateTime(ts),context,level,event,data
FROM logs
WHERE device_id = 'some_uuid' AND week = '2021-07-05'
ORDER BY ts DESC
LIMIT 10
OFFSET 0;
SELECT device_id,toDateTime(ts),context,level,event,data
FROM logs
WHERE device_id = 'some_uuid' AND week = '2021-07-05';
AFAIK,除非您指定了确切的分区格式,否则 CH 将为您的 CREATE TABLE
语句使用按月分区(即 toYYYYMM()
)。您可以通过查看 system.parts
table:
来检查
SELECT
partition,
name,
active
FROM system.parts
WHERE table = 'logs'
所以,如果你想按周存储数据,我想分区可能是这样的
...
ORDER BY (device_id, ts)
PARTITION BY toMonday(week)
这也是一条很好的信息:Using Partitions and Primary keys in queries
我们项目中出现以下问题,无法解决。 我们有大量的日志数据,我们从 MongoDB.
转到 ClickHouse我们的table是这样创建的:
CREATE TABLE IF NOT EXISTS logs ON CLUSTER default (
raw String,
ts DateTime64(6) MATERIALIZED toDateTime64(JSONExtractString(raw, 'date_time'), 6),
device_id String MATERIALIZED JSONExtractString(raw, 'device_id'),
level Int8 MATERIALIZED JSONExtractInt(raw, 'level'),
context String MATERIALIZED JSONExtractString(raw, 'context'),
event String MATERIALIZED JSONExtractString(raw, 'event'),
event_code String MATERIALIZED JSONExtractInt(raw, 'event_code'),
data String MATERIALIZED JSONExtractRaw(raw, 'data'),
date Date DEFAULT toDate(ts),
week Date DEFAULT toMonday(ts)
)
ENGINE ReplicatedReplacingMergeTree()
ORDER BY (device_id, ts)
PARTITION BY week
我是运行这样的查询
SELECT device_id,toDateTime(ts),context,level,event,data
FROM logs
WHERE device_id = 'some_uuid'
ORDER BY ts DESC
LIMIT 10
OFFSET 0;
这是集合中 10 行的结果。 已用:6.23 秒
第二个没有顺序、限制和偏移量:
SELECT device_id,toDateTime(ts),context,level,event,data
FROM logs
WHERE device_id = 'some_uuid'
这是结果 耗时:7.994 秒。 每 500 行 130000+
太慢了。
似乎 CH 处理了 table 中的所有行。 CH有什么问题需要提高速度吗?
MongoDB 上的相同实现需要 200-500 毫秒 max
叶戈尔!当您提到“我们从 MongoDB 转到 ClickHouse”时,您的意思是您从 MongoDB 切换到 ClickHouse 来存储您的数据吗?或者您以某种方式连接到 ClickHouse,从 MongoDB 到您所指的 运行 查询?
我不确定你是如何摄取数据的,但让我们专注于阅读部分。
对于MergeTree家族,ClickHouse是分段写入数据的。因此,将时间戳作为 where 子句的一部分至关重要,这样 ClickHouse 就可以确定您要读取的部分并跳过大部分不需要的数据。否则,它将扫描所有数据。
我想这些查询会更快地进行扫描:
SELECT device_id,toDateTime(ts),context,level,event,data
FROM logs
WHERE device_id = 'some_uuid' AND week = '2021-07-05'
ORDER BY ts DESC
LIMIT 10
OFFSET 0;
SELECT device_id,toDateTime(ts),context,level,event,data
FROM logs
WHERE device_id = 'some_uuid' AND week = '2021-07-05';
AFAIK,除非您指定了确切的分区格式,否则 CH 将为您的 CREATE TABLE
语句使用按月分区(即 toYYYYMM()
)。您可以通过查看 system.parts
table:
SELECT
partition,
name,
active
FROM system.parts
WHERE table = 'logs'
所以,如果你想按周存储数据,我想分区可能是这样的
...
ORDER BY (device_id, ts)
PARTITION BY toMonday(week)
这也是一条很好的信息:Using Partitions and Primary keys in queries