Clickhouse Join --单机hashjoin
作者:互联网
clickhouse单机join操作默认采用hash join算法,可选用merge join。其中merge join算法数据会溢出到磁盘,性能相比前者差。本文主要介绍hashjoin实现的join操作。
从right table读取该全量表数据,在内存中构建hashmap,从left table分批读取数据,根据join key到hash map中进行查找,如果命中,则该数据作为join输出。从实现可以看出,如果right table数据量超过单机可用内存限制时候,则join操作无法完成。通常,两表join时,将较小的作为right join
Clickhouse 分布式Join
join中涉及到的left_table和right_table是分布式表
有以下几种方式:
Broadcast JOIN
Shuffle Join
Colocate JOIN
clickhouse集群并未实现完整意义上的shuffle join,实现了类似broadcast join,通过事先完成数据重分布,能够实现colocate join
clickhouse的分布式join查询可以分为两类,带global关键字的,和不带global关键字的情况。
普通join实现
无global关键字的join如何实现:
initiator将sql左表分布式表 S 替换成本地表,形成 S‘
将S’分发到集群的每个节点
当集群节点执行S‘,并将结果汇总到initiator节点
initiator节点将结果返回给客户端。如果右表是分布式表,则及群众每个节点会去执行分布式查询,就会存在一个非常严重的读放大现象。假设集群有N个节点,则右表查询会在集群中执行N*N次。
select a_.i,a_.s,b_.t from a_all as a_ join b_all as b_ on a_.i = b_.i
其中a_all,b_all是分布式表,对应本地表名为a_local,b_cloal。则该sql在分布式查询执行的时间顺序为:
initiator收到查询请求
initiator执行分布式查询,本届点和其他节点执行select a_.i,a_.s,b_.t from a_local as a_ join b_all as b_ on a_.i = b_.i,即左表更改为本地表
集群节点收到请求后,分析出右表分布式表,在本地b_local查询结果,并计作subquery
查到subquery后,在与a本地表进行join
各节点执行完毕后,向initiator发送数据
shuflle join简化版,right表全量
Global join实现
global join计算过程如下:
若右表为子查询,则initiator完成子查询计算
initiator将右表数据发送到其他集群节点
集群节点将本地左表与右表数据进行join计算
集群其他节点将结果发回给initiator节点计算
initiator将结果汇总,发给客户端
global join可以看作一个不完整的broadcast join实现,如果join的右表数据量比较大,就会占用大量网络带宽,导致查询性能下降
global join将右表的查询在initiator节点上完成后,通过网络发送到其他节点,避免其他节点重复计算,从而避免查询方法。
分布式join最佳实践
减少join右表数据量,小表作为右表,尽可能增加过滤条件
利用global join避免查询放大带来性能损失
数据预分布实现colocate join。将涉及join的表按join key分片
查询时候将右边的表换成本地表
标签:initiator,Join,_.,--,查询,hashjoin,join,节点,分布式 来源: https://www.cnblogs.com/shudazhaofeng/p/16373241.html