Clickhouse distributed 分布式聚合查询,二次聚合问题


在工作中遇到了Clickhouse distributed 分布式聚合查询,二次聚合问题:

全局表的分布键值取cityHash64进行分片,相同的target_value 被写入同一个分片中,这样对target_value 进行聚合操作,

SQL语句应该分别在每个分片进行查询(SQL根据全局表的分布键值下推),然后把各个分片的聚合结果传输到SQL下发节点,直接返回结果:

1)SQL下发后,分片将SQL中的全局表转换为本地表;

2)直接运行对自己分片的本地表进行聚合查询;

3)将每个分片运行结果传输到SQL下发节点,返回给客户端;

但是,在实际使用中,并未出现希望的场景。

查看了SQL的执行计划得知:

1)SQL下发后,分片将SQL中的全局表转换为本地表;

2)每个分片将where条件的结果分别查出;

3)每个分片,将查出的中间数据,传输到SQL下发节点;

4)由下发节点来进行中间数据的聚合操作,得出SQL最终结果集,返回给客户端;

1、表结构如下

----全局表

create table test_all

(

target_type String,

target_value String,

cnd_type String,

cnd_value String,

target_time DateTime

) ENGINE= Distributed('ch_name','test_db','test_local',cityHash64(target_value ));

----本地表

create table test_local

(

target_type String,

target_value String,

cnd_type String,

cnd_value String,

target_time DateTime

) ENGINE= MergeTree

Partition by toDate(target_time)

order by (target_value ,cnd_value );

2、SQL如下

select 

target_value ,target_type,cnd_value ,cnd_type ,count() matchCount

from test_all where  toDate(target_time) >=toDate('2021-05-09') and toDate(target_time) <=toDate('2021-06-09')

group by  target_value ,target_type,cnd_value ,cnd_type

having matchCount>7;

时间范围内数据总量为1.1亿条,经过筛选与排序后的数据油7千万条,运行时间50-60s之间。

如果换成本地表,则需要SQL运行7s左右:

select 

target_value ,target_type,cnd_value ,cnd_type ,count() matchCount

from test_all where  toDate(target_time) >=toDate('2021-05-09') and toDate(target_time) <=toDate('2021-06-09')

group by  target_value ,target_type,cnd_value ,cnd_type

having matchCount>7;

3、问题解决

1)在分布式(DistributedMergeTree)表中用target_value 做分片键;
2)在分片表(也叫本地表)中用target_value 做order by
3)然后设置参数distributed_group_by_no_merge = 1
这个参数(默认为0,表示默认功能关闭)含义就是本地表做完聚合后,不再在分布式表中聚合所有数据。因此需要确保相同的target_value 值出现在同一个分片上(步骤1确保了这一点)。这样在每个分片上做group by之后,在分布式表做数据汇总即可。从而提升了查询性能。
4、优化后SQL

select 

target_value ,target_type,cnd_value ,cnd_type ,count() matchCount

from test_local where  toDate(target_time) >=toDate('2021-05-09') and toDate(target_time) <=toDate('2021-06-09')

group by  target_value ,target_type,cnd_value ,cnd_type

having matchCount>7

settings distributed_group_by_no_merge = 1;

运行时间由原来的50-60s,将为17s左右。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM