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 不是万能的。局部聚合的压缩率取决于数据倾斜程度,倾斜严重时效果打折。
分片键选得好,大部分查询能走静态算子;选得差,动态重分布会成为常态。这是建表时就要想清楚的事,事后调优成本高得多。