clickhouse 慢查询解决方案
单表
使用 prewhere
多表
in代替 join 【等值查询】
记录: 第一次使用 clickhouse join 了 2 张表,耗时 用了 2-3 秒,速度不够
看网上的解决方法是,使用 小表 放 左边,因为 clickhouse 永远都是 左边 去 查右表的数据
JOIN操作时一定要把数据量小的表放在右表,ClickHouse中无论是Left Join 、Right Join还是Inner Join永远都是拿着左表中的每一条记录到右表中查找该记录是否存在,所以右表必须是小表
clickhouse 会把 所有的数据从右表加载到内存,右表数据量过大,还会爆内存,这就很难受
谓词下推
这里举个例子,我们来看两个查询结果一致的 sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
select count(vr.id),vr.result_type ,idc.name,crg.project_name from (
select * from v_result5 vr
WHERE db_archive_year = 2022 and db_archive_month = 12
) vr
join cmdb_idc idc on vr.idc_id = idc.id
join cmdb_resource_group crg on crg.resource_id = vr.id
and crg.resource_type = vr.resource_type
where vr.db_archive_year = 2022 and vr.db_archive_month = 12 and vr.delete_flag = 0
and crg.db_archive_year = 2022 and crg.db_archive_month = 12 and crg.delete_flag = 0
and idc.db_archive_year = 2022 and idc.db_archive_month = 12 and idc.delete_flag = 0
group by crg.project_name, idc.name,vr.result_type
limit 300
|
这个 sql 首次查询用 了 7秒, 后续查询 都是 接近了 1秒 , 0.8 秒的查询速度
我们使用谓词下推, join 里面 使用子查询,缩小 join 表的范围,就可以大大减少数据集,我们会看到 上面 有 125万条数据,明显 数据量过大了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
select count(vr.id),vr.result_type ,idc.name,crg.project_name from (
SELECT
id,
idc_id,
asset_number,
cabinet_id,
sn,
'服务器' AS result_type,
1 AS col_type,
2 AS resource_type,
db_archive_year,
db_archive_month
FROM test.cmdb_physical_machine AS cpm
WHERE cpm.db_archive_year = 2022 and cpm.db_archive_month = 12 and cpm.delete_flag = 0
) vr
join (select * from cmdb_idc idc where idc.db_archive_year = 2022 and idc.db_archive_month = 12 and idc.delete_flag = 0) idc on vr.idc_id = idc.id
join (select * from cmdb_resource_group crg where crg.db_archive_year = 2022 and crg.db_archive_month = 12 ) crg on crg.resource_id = vr.id
and crg.resource_type = vr.resource_type
group by crg.project_name, idc.name,vr.result_type
limit 300
|
在 join 里面使用子查询,就减少为 几千行数据