在 ClickHouse 集群里,把分布式表与本地表做关联是很常见的操作。只要分片键设计得当,完全可以避免GLOBAL JOIN带来的网络开销。
问题现象
集群里有按Id分片的分布式表A_distributed,同时每个节点上有一张本地表B_local。需求是:从A_distributed取数,与B_local按Id关联,在每个分片上各自完成 JOIN 后汇总结果,明确不走GLOBAL JOIN。
原因分析
这正是 ClickHouse 分布式查询的默认工作方式,不需要额外配置。查询分布式表时,发起节点(initiator)会把查询改写后下发到各个分片;每个分片用自己本地的数据执行查询计划的本地部分;最后把中间结果回传给发起节点汇总。
JOIN 的处理分两种情况:
- 不使用
GLOBAL JOIN/GLOBAL IN:JOIN 在各个目标节点本地执行。右表是本地表时,直接用本节点的本地数据;右表是分布式表时,会被展开成一次跨分片的子查询。 - 使用
GLOBAL JOIN:右表先在发起节点上计算并收敛成临时表,再分发到所有分片,每个分片与这张完整的右表关联。
关键在于左表的分布式语义:A_dis