GBase 8a分布式执行计划:JOIN、GROUP BY、排序去重算子怎么选

Feng 20 阅读 AI技术

GBase 8a 的执行计划里,JOIN、GROUP BY、ORDER BY 这几类核心运维各自对应一套分布式落实算子。算子分两种:静态无迁移、动态重分布。选对了,数据不动、并行度拉满;选错了,跨节点搬数据,性能直接掉一个档。

JOIN 算子:先看关联字段是不是分片键

静态 Hash Join 是最优解。两张表都是哈希分布表,关联字段正好是分片键,每台机器拿本地分片直接关联,零跨节点传输,并行度最高。这是优先推荐的关联方式。

小表广播 Join 适合大表分片、小表数据量小的场景。把小表全量广播到所有数据机器,各节点本地完成大小表关联,避免大表重分布。小表关联用它,稳。

动态重分布 Hash Join 是兜底。关联字段不是分片键,本地没法完成关联,优化器自动对其中一张或两张表重新分片、跨机器迁移数据后再关联。有数据传输开销,性能次之。

GROUP BY 算子:聚合字段决定要不要搬数据

静态 GROUP BY 同样是最优路径。GROUP BY 字段包含表分片键,各机器本地分片独立完成聚合,只把最终结果汇总到管理节点,无数据迁移,性能极高。

GROUP BY 字段不含分片键时,本地聚合结果分散,必须先把数据按聚合字段重分布,再做全局聚合。这就是动态重分布 GROUP BY,数据迁移开销跑不掉。

两阶段 GROUP BY 是大数量聚合的核心调优策略。先在各机器做局部聚合压缩数据量,再全局汇总聚合,跨节点传输的数据量能大幅压缩。聚合量大时优先考虑它。

排序与去重:filesort 是个信号

GBase 8a 默认优先机器本地排序,再全局归并排序。执行计划里出现 Using filesort,说明没走索引排序,需要手动调优索引或改写排序条件。

这里有个坑:filesort 不一定报错,但它是性能隐患。上线前用 EXPLAIN 过一遍执行计划,看到它就得处理。

DISTINCT 去重的底层逻辑和 GROUP BY 复用同一套聚合算子,天然带分布式并行去重能力。所以去重慢的时候,排查思路和 GROUP BY 是一致的——看字段和分片键的关系。

验证算子是否走对,靠 EXPLAIN

判断执行计划走了哪类算子,最直接的办法是 EXPLAIN 看计划输出。重点确认三件事:JOIN 有没有触发重分布、GROUP BY 是否出现两阶段聚合、排序有没有 filesort。

校验命令示例:

判定标准很明确:计划里出现 Redistribute 或 Broadcast 字样,说明发生了数据迁移;本地聚合节点数等于数据节点数,说明是静态算子。

适用边界与风险

静态算子只适合关联字段或聚合字段命中分片键的场景,表设计阶段就要考虑。动态重分布算子通用,但数据量大时网络和磁盘 IO 压力明显,不建议在生产环境对大表频繁触发。

两阶段 GROUP BY 不是万能的。局部聚合的压缩率取决于数据倾斜程度,倾斜严重时效果打折。

分片键选得好,大部分查询能走静态算子;选得差,动态重分布会成为常态。这是建表时就要想清楚的事,事后调优成本高得多。

Feng
这位作者很神秘,还没有填写简介。