文章目录
问题
一个查询接口,涉及多个clickhouse 查询,查询用时一下变成要60s
表结构类似如下
bash
CREATE TABLE demo.test_local
(
`id` UUID,
`date` DateTime,
`type` String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/test_local', '{replica}')
PARTITION BY data_date
ORDER BY id
TTL data_date + toIntervalDay(10)
SETTINGS index_granularity = 8192
分析第一步
从资源竞争入手,因为这里面一个接口很多个查询
通过执行SHOW PROCESSLIST 命令,得到执行详情
这里我得到的数据
CPU 竞争 :OSCPUWaitMicroseconds 高达 2.5 亿微秒(~250秒),说明 CPU 调度延迟严重。
磁盘 I/O 瓶颈 :ThreadPoolReaderPageCacheMiss 高(如 5,737 次缓存未命中),AsynchronousReadWaitMicroseconds 超过 4.5 亿微秒(~453秒),表明磁盘读取成为瓶颈
可以得到的结论,cpu 等待时间长,磁盘读的数据量大
调整第一步
增量cpu资源,调到48c
执行时间变成30s
观察多磁盘读
从执行sql来看,都有时间条件作为下推来过滤数据,好像没生效
观察create table sql
发现 排序竟然是用的id,不是date,这里本来应该是用date的
bash
CREATE TABLE demo.test_local
(
`id` UUID,
`date` DateTime,
`type` String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/test_local', '{replica}')
PARTITION BY data_date
ORDER BY id
TTL data_date + toIntervalDay(10)
SETTINGS index_granularity = 8192
修改create table sql 接口时间变成5s左右
bash
CREATE TABLE demo.test_local
(
`id` UUID,
`date` DateTime,
`type` String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/test_local', '{replica}')
PARTITION BY data_date
ORDER BY date
TTL data_date + toIntervalDay(10)
SETTINGS index_granularity = 8192
继续观察sql
发现有很多基于type 的精确查询
bash
CREATE TABLE demo.test_local
(
`id` UUID,
`date` DateTime,
`type` String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/test_local', '{replica}')
PARTITION BY data_date
ORDER BY (date,type)
TTL data_date + toIntervalDay(10)
SETTINGS index_granularity = 8192
再次修改create table sql ,把type 加入排序建
对type增加跳数索引
ALTER TABLE demo.test_local
ADD INDEX type_set_index (type) TYPE set(100) GRANULARITY 8;
结果接口耗时1s