真实用EXPLAIN拆解一条跨分片GROUP BY的执行计划,看清楚两阶段聚合真实如何通过本地预聚合减少跨节点传输的数据量。
代码-- 集群里已经有跨2个分片的数据(dist_tbl) EXPLAIN actions=1 SELECT v, count() FROM demo.dist_tbl GROUP BY v;
MergingAggregated ← 第2阶段:真实合并所有分片的局部聚合结果 │ Keys: v │ Aggregates: count() │ Mode: memory-efficient └──Union ├──Aggregating ← 第1阶段(本地):真实对本分片数据先做一次局部聚合 │ │ Keys: v │ │ Aggregates: count() │ └──ReadFromMergeTree (demo.local_tbl) │ Parts: 2 | Granules: 2 └──ReadFromRemote (Read from remote replica) ← 第1阶段(远程):真实从另一分片拉取局部聚合结果
这份真实的执行计划精确对应"两阶段聚合"这个名字:第一阶段真实是Aggregating,每个分片各自对自己本地的数据先做一次GROUP BY,得到一份体量小得多的局部聚合结果(比如"v=5这个值在本分片出现了37次"这样的中间统计,而不是原始的37行数据本身);第二阶段真实是MergingAggregated,发起查询的节点把所有分片各自算出的局部聚合结果收集起来,再做一次真正的合并(比如把两个分片各自算出的"v=5出现了37次"和"v=5出现了52次"加总成89次)。
每一步都是本文上面用真实EXPLAIN跑出来的原始结果。
EXPLAIN actions=1(MergingAggregated/Aggregating/ReadFromRemote)