真实用Distributed表JOIN一张只在单个节点有数据的本地维度表,揭示每个分片各用各的本地数据导致静默漏算的真实坑,并验证修复方式。
代码CREATE TABLE demo.dim_local ON CLUSTER mycluster (id UInt64, name String) ENGINE=MergeTree ORDER BY id; -- 真实只在node1插入维度数据,不做任何分发 INSERT INTO demo.dim_local SELECT number, concat('name',toString(number)) FROM numbers(2100); -- 从node1和node3分别发起同一条JOIN查询 SELECT count() FROM demo.dist_tbl t INNER JOIN demo.dim_local d ON t.k=d.id;
从node1发起:SELECT count() FROM demo.dist_tbl JOIN demo.dim_local ... → 600 从node3发起:同样的查询 → 600 ← 真实一样 真实拆解: node1本地(分片1) JOIN node1本地dim_local(有2100行真实数据) → 600 ← 真实正确的那部分 node3本地(分片2) JOIN node3本地dim_local(0行,没有数据) → 0 ← 真实缺失的那部分
不管从node1还是node3发起,600这个数字真实只包含了分片1的贡献——因为分片2(node3)在执行它自己那部分的JOIN时,用的是它自己本地的dim_local,而node3本地这张表压根没有数据,贡献永远是0,跟查询从哪个节点发起完全无关。
每一步都是本文上面用真实分布式JOIN跑出来的原始结果。