ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Apache Doris 4.0.8 Join 调优(第 11 篇):一条 Join 怎样吃光单台 BE,倾斜为何比大表更危险

Apache Doris 4.0.8 Join 调优(第 11 篇):一条 Join 怎样吃光单台 BE,倾斜为何比大表更危险 两张百亿行表 Join 不一定出事一张千万行表却可能让单台 BE OOM。区别不在总行数而在customer_id 0是否吞掉了 60% 数据。Shuffle 按 Join Key 分发时这些行会准确地落到同一个分区。大表消耗全局资源倾斜把全局资源压缩成一台机器的生死线。四种 Join 的网络账单Join 官方文档 给出四种分布方式方式网络量适用条件失败方式BroadcastN × T(R)右表足够小右表复制到每个实例内存放大ShuffleT(S) T(R)两边大且 Key 均匀热点 Key 集中到单节点Bucket ShuffleT(R)左表 Join Key 命中 Bucket KeyBucket 少或倾斜时并行度不足Colocate0同组、同 Bucket、同副本布局建表约束强组不稳定会失效网络量最小不等于一定最快。Bucket 只有三个时Colocate 可能因为并行度过低输给普通 Shuffle。一个热点值足以摧毁 Hash Shuffle测试数据中把缺失客户统一填成 0SELECTc.level,SUM(o.amount)FROMfact_order oJOINdim_customer cONo.customer_idc.customer_idGROUPBYc.level;如果customer_id 0占 60%Hash Shuffle 后某个实例接收绝大多数订单。Profile 会出现Exchange InputRows: Max 远大于 Avg HashJoin ProbeRows: Max 远大于 Avg PeakMemoryUsage: 单实例突增 SpillWriteBytes: 热点实例独有总输入只有平衡数据的一半也可能因为单实例上限更早失败。Broadcast 有时是解决倾斜不只是小表优化右表足够小时Broadcast 让大表保持本地扫描不再按热点 Join Key Shuffle。官方 Hint 文档也将严重 Key 倾斜列为 Broadcast 的适用场景。SELECT/* SET_VAR(enable_profiletrue) */c.level,SUM(o.amount)FROMfact_order oJOIN[broadcast]dim_customer cONo.customer_idc.customer_idGROUPBYc.level;但 Broadcast 的成本是右表大小乘实例数。统计信息把 20GB 右表误判成 20MB 时强制 Broadcast 会把所有 BE 一起推向内存危险。Hint 只能作为有证据的临时控制不是永久修复。Runtime Filter 减少 Probe不会打散热点Runtime Filter 官方文档 说明 Build 侧生成过滤条件并下推到大表 Scan可减少无关行的 I/O 和网络。如果 Build 侧只有 4% 客户参与活动Runtime Filter 很有效如果 60% 订单都对应同一个有效热点客户它只能确认这些行必须保留不能把一个 Key 分给多个 Hash 分区。倾斜修复需要改变数据或计算形态将无业务意义的 0、NULL 单独过滤或分支处理对热点 Key 做 Salt并在结果端二次聚合小右表改 Broadcast稳定大表 Join 设计 Colocate修正统计信息让 CBO 看见真实基数。Salt 会放大维表并增加二次聚合Colocate 会增加建表和运维约束。每一种修复都需要写出代价。排障先比较实例不要先改 SQLEXPLAIN SHAPE PLAN确认 Join 分布。Profile 比较 Exchange、ProbeRows 和内存的 Min/Avg/Max。SQL 统计 Top Join Key 占比。用 Broadcast 或过滤热点做单变量对照。复测 P99、网络、峰值内存和 Spill。如果 Max/Avg 差距没有收敛只是总耗时偶然下降根因仍在。源码只追 DistributionSpec 到 ExchangeDoris4.0.8源码阅读从 Nereids 对 Join 的DistributionSpec选择开始再看物理计划生成 Exchange最后追 BE Hash Partition 发送与 Join Build/Probe。Runtime Filter 则追 Build 侧生成、合并和 Scan 下推。源码应回答计划为什么选择 Shuffle、热点为什么落到同一接收端而不是罗列所有 Join 算法。Join 优化的第一问题不是两张表有多大而是哪一批行最终会被迫挤进同一个执行实例。官方资料JoinsJoin OptimizationAdjusting Join ShuffleRuntime Filter
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进