ClickHouse - SELECT 数据行太慢

问题描述

在我们的项目中出现了以下问题,我们无法解决。 我们有大量日志数据,我们从 MongoDB 转到 ClickHouse。

我们的表是这样创建的:

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,data 
FROM logs 
WHERE device_id = 'some_uuid'

这是结果 Elapsed: 7.994 sec. 对于每 500 行 130000+

太慢了。

似乎 CH 处理了表中的所有行。有什么问题,需要提高CH的速度吗?

MongoDB 上的相同实现需要 200-500 毫秒 最大

解决方法

叶戈尔!当您提到“我们从 MongoDB 转到 ClickHouse”时,您的意思是您从 MongoDB 切换到 ClickHouse 来存储数据吗?或者您以某种方式从 MongoDB 连接到 ClickHouse 以运行您所指的查询?

我不确定你是如何摄取数据的,但让我们专注于阅读部分。

对于 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,data 
FROM logs 
WHERE device_id = 'some_uuid' AND week = '2021-07-05';

AFAIK,除非您指定了确切的分区格式,否则 CH 将对您的 toYYYYMM() 语句使用按月分区(即 CREATE TABLE)。您可以通过查看 system.parts 表来检查:

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