You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ClickHouse中使用分区键优化JOIN 实现类似亲和性共置的分布式关联

ClickHouse亲和性共置JOIN实现方案

前提修正

首先需要纠正一个配置误区:分区键仅控制单节点内部的数据拆分规则,不负责跨节点的数据分片分布,要实现和Apache Ignite一致的亲和性共置,需要先保证以下配置正确:

  • 两张表对应的分布式表归属同一个ClickHouse集群
  • Employee表对应的分布式表分片键设置为ID,Attendance表对应的分布式表分片键设置为Employee_ID
  • 两张分布式表使用完全相同的分片规则(如均使用cityHash64计算分片、集群分片总数一致),确保相同ID的员工数据和对应考勤数据始终落在同一个分片节点上。

两种实现方案

方案一:自动优化本地JOIN(21.8及以上版本支持)

执行查询前先开启两个会话优化参数,ClickHouse会自动识别共置的分片规则,直接在每个节点本地完成JOIN后汇总结果,不需要跨节点拉取数据:

SET distributed_joins_use_own_sharding_key = 1;
SET optimize_skip_unused_shards = 1;

之后直接写关联查询即可,关联键必须为两张表的分片键:

SELECT e.ID, e.Name, a.Date, a.isPresent
FROM distributed_employee e
INNER JOIN distributed_attendance a
ON e.ID = a.Employee_ID;

方案二:手动下发本地计算(全版本兼容)

如果需要更可控的执行逻辑,或是使用21.8之前的旧版本,可以直接通过集群查询将计算逻辑下发到每个节点本地执行,再合并结果:

SELECT * FROM cluster(
    '替换为你的集群名称',
    'default',
    '
        SELECT e.ID, e.Name, a.Date, a.isPresent
        FROM employee_local e
        INNER JOIN attendance_local a
        ON e.ID = a.Employee_ID
    '
);

其中employee_local、attendance_local为节点上存储的本地MergeTree表名,该语句会直接在每个分片节点执行本地表JOIN,仅返回最终结果到发起查询的节点合并。

之前方案失效原因说明

  • GLOBAL JOIN会先将右表全量拉取到发起查询的节点,再分发到所有分片,完全不利用共置特性
  • 未开启优化参数的普通LOCAL JOIN默认不会识别分片键共置规则,仍会跨节点拉取关联需要的数据

内容的提问来源于stack exchange,提问作者Vineeth Mohan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 06:06:01