Spark DynamicJoinSelection 规则根据AQE统计信息动态调整Join策略

作者:鸿乃江边鸟日期:2026/4/9

背景

本文基于Spark 3.5.3
在Spark引入了AQE以后,Spark在运行的时候能够拿到运行时候的Shuffle统计信息,这些信息可以更好的来调整join的策略,当下规则下这种策略的调整是通过增加hint来进行控制的, 规则的目的是防止负优化

分析

这里会有三种优化场景:
1. 检测大量空分区 → 添加 NO_BROADCAST_HASH HINT
对应的代码如下:

1 private def hasManyEmptyPartitions(mapStats: MapOutputStatistics): Boolean = {
2    val partitionCnt = mapStats.bytesByPartitionId.length
3    val nonZeroCnt = mapStats.bytesByPartitionId.count(_ > 0)
4    partitionCnt > 0 && nonZeroCnt > 0 &&
5      (nonZeroCnt * 1.0 / partitionCnt) < conf.nonEmptyPartitionRatioForBroadcastJoin
6  }
7

这里有个配置spark.sql.adaptive.nonEmptyPartitionRatioForBroadcastJoin默认是0.2
这种情况主要是在于AQE 中 等值join 转换 BroadcastHashJoinExec,防止 转化为BroadcastHashJoinExec,因为此时的shuffle数据已经有了,而且非空的分区数据比较少,直接shuffle join会更快,因为broadcast join还会有broadcast 的过程
2.分区数据小 → 添加 PREFER_SHUFFLE_HASH HINT
对应的代码如下:

1private def preferShuffledHashJoin(mapStats: MapOutputStatistics): Boolean = {
2    val maxShuffledHashJoinLocalMapThreshold =
3      conf.getConf(SQLConf.ADAPTIVE_MAX_SHUFFLE_HASH_JOIN_LOCAL_MAP_THRESHOLD)
4    val advisoryPartitionSize = conf.getConf(SQLConf.ADVISORY_PARTITION_SIZE_IN_BYTES)
5    advisoryPartitionSize <= maxShuffledHashJoinLocalMapThreshold &&
6      mapStats.bytesByPartitionId.forall(_ <= maxShuffledHashJoinLocalMapThreshold)
7  }
8

这里有spark.sql.adaptive.maxShuffledHashJoinLocalMapThreshold(默认是0),只要所有分区大小小于这个阈值,就使用hash join,因为如果使用SortMergeJoin的话,在join之前还会有Sort的操作,而hash join没有这个sort操作,数据量小的情况,hash join更快

* 3.两者都满足 → 添加 SHUFFLE_HASH HINT
如果以上两种情况都满足,则直接加 SHUFFLE_HASH HINT

注意:以上发生的转换是在用户没有手动指定HINT的前提下

总体的决策逻辑流程如下:

1                              ┌─────────────────────────┐
2                                Join 节点 (ExtractEquiJoinKeys) 
3                              └───────────┬─────────────┘
4                                          
5                    ┌─────────────────────┼─────────────────────┐
6                                                             
7           检查 Left 子节点                            检查 Right 子节点
8                                                             
9                                                             
10        ┌───────────────────────┐              ┌───────────────────────┐
11         ShuffleQueryStageExec                ShuffleQueryStageExec 
12          isMaterialized                     isMaterialized     
13          mapStats.isDefined                 mapStats.isDefined 
14        └───────────┬───────────┘              └───────────┬───────────┘
15                                                             
16         ┌──────────┴──────────┐                ┌──────────┴──────────┐
17                                                                   
18   Many Empty Partitions?  All Partitions     Many Empty Partitions?  All Partitions
19                              Small?                                     Small?
20                                                                       
21    ─────────────       ─────────────        ─────────────       ─────────────
22                                                                         
23                                                                         
24    demote BHJ:          prefer shuffle       demote BHJ:          prefer shuffle
25    NO_BROADCAST_HASH    hash: PREFER_         hash: PREFER_        hash: PREFER_
26                        SHUFFLE_HASH          SHUFFLE_HASH         SHUFFLE_HASH
27

Spark DynamicJoinSelection 规则根据AQE统计信息动态调整Join策略》 是转载文章,点击查看原文


相关推荐


金融和电商行业如何使用网络监控保障业务稳定?
运维行者_2026/4/1

在金融和电商的世界里,系统"稳定"从来不是一句口号------它是真金白银的保障。一笔支付交易卡顿3秒,可能让客户放弃下单;一次核心数据库响应延迟,就可能触发监管警报;一张快递面单打印失败,背后是成百上千个订单履约受阻。这些看似微小的技术波动,在高并发、强实时的业务场景中会被迅速放大,直接侵蚀用户体验、品牌信誉甚至合规底线。 OpManager 深知,对金融与电商企业而言,网络监控的意义远不止"看设备是否在线"。它必须能穿透复杂的IT架构,预判风险、快速定位、自动响应,并在关键时刻成为业务连续


【Linux】网络之http协议
爱吃生蚝的于勒2026/3/24

文章目录 URL🚩HTTP协议格式请求格式HTTP常用方法 响应格式常见状态码HTTP常见Header 🚩模拟实现HTTP服务器⭐Cookie URL 我们所说的网址就是URL 如果在参数中出现?/特殊字符,会自动转义,/ ?字符已经被url特殊处理了 ‘+’被转义为%2b 🚩HTTP协议格式 请求格式 请求行:方法+URL+版本号+\r\n 请求报头:每行一对键值对+\r\n \r\n空行,(没有空行的话无法区分报头和正文) 正文,(怎么确定正文


C++入门基础
全球便秘冠军保持者2026/3/16

C++的第一个程序 #include<stdio.h> int main() { printf("Hello World!\n"); return 0; } 这是我们使用的c++的编译器写的c语言的“Hello World!”,说明c++的编译器可以兼容c语言的语法 那我们来看一下用c++写的“Hello World!” #include <iostream> using namespace std; int main() { cout << "Hello World!"


拒绝写重复代码,试试这套开源的 SpringBoot 组件,效率翻倍~
皮皮林5512026/3/7

目录 1 简介 2 快速入门 2.1 Spring Boot 接口开发现状 2.2 快速入门 1 简介 Graceful Response 是一个 Spring Boot 技术栈下的优雅响应处理器,提供一站式统一返回值封装、全局异常处理、自定义异常错误码 等功能,使用 Graceful Response 进行 web 接口开发不仅可以节省大量的时间,还可以提高代码质量,使代码逻辑更清晰。 强烈推荐你花 3 分钟学会它! 本项目案例工程代码:https://github.com/fe


程序员的明天:AI 时代下的行业观察与个人思考
勇哥Java实战2026/2/27

这篇文章分享了我对 AI 时代下,软件行业发展以及程序员命运走向的 5 点思考,供大家参考。 1 匠人时代落幕 Redis 之父 antirez,最近写了一篇文章 《 Don't fall into the anti-AI hype 》,读完之后,我深有感触。 文章的观点非常明确: AI 不仅改变了编码方式,更重塑了软件行业的价值结构和职业路径,程序员需要从“手动编码”转向“设计系统与与 AI 协作” 。 过去的软件行业,其实有一种很典型的“匠人红利”。谁代码写得更优雅,谁框架更熟,谁对某个


QT & QML 总结备查
瞰百2026/2/19

QT & QML 总结备查 首要注意,在桌面端开发QT可免费商用,而嵌入式端QT商用则收费。 各种 UI 库的总结和对比: Cpp-Learning/C-C++实用库备查.md at main · Staok/Cpp-Learning。 文章所在 Github 仓库 Staok/QT-QML-Learning: QT & QML 总结备查文章 会保持最新,其它地方的不会跟进。 常看常新 QT 安装:网搜 Qt Creator 下载和安装即可。 编译器:对于 Win 上


英语语法笔记:英语不应该成为开发工程师的发展瓶颈
修己xj2026/2/11

前几天,是公司成立二十周年的年会。老板作了一场题为《穿越寒冬,求实存善》的演讲。那一刻我在想:当寒意渐浓,作为领航者,他思考的是如何带领公司扛过这场冬天;那作为程序员的我们,又该如何穿越自己的寒冬呢? Vue 作者尤雨溪曾坦言:“不仅英语差会成为瓶颈,英语好还能成为优势,因为学习效率会比别人高。像我这样半路出家自学的人,只能靠英语了……”确实,无论是阅读技术文档、参与开源社区、在 Stack Overflow 寻找答案,还是追踪最新技术资讯、争取一份远程机会,英语早已不是可选项,而是必修课——是


AI - 通过 Docker 来安装与访问 OpenClaw
LinXunFeng2026/2/2

欢迎关注微信公众号:FSA全栈行动 👋 一、简介 这是我在 Mac 上通过 Docker 来安装和配置 OpenClaw 的一份记录,随着文章从上到下一步步做就可以了。 二、docker 拉取 Ubuntu 镜像 docker pull ubuntu:latest 创建容器 创建容器,并映射 18789 端口 docker run -it -p 18789:18789 --name openclaw ubuntu 搭配 Docker 容器的分离快捷键,先按 Ctrl+P,再按 Ctrl+


🚀 纯前端离线局域网P2P大文件断点传输:别让你的照片墙崩了
子兮曰2026/1/23

前言:小明和他的照片墙危机 想象一下,你是小明,一个热爱摄影的程序员。周末去爬山拍了一堆4K高清照片,总共3GB,准备发给老婆分享。微信传?算了,压缩后画质渣得像像素风。网盘?离线状态下连不上。蓝牙?慢得像蜗牛在跑步。你急得团团转,突然灵机一动:用电脑直接传啊!可是怎么在浏览器里实现局域网P2P大文件传输,还得支持断点续传?别急,今天咱们就聊聊这个技术方案。 技术背景:P2P不是什么新鲜玩意儿 P2P(点对点)传输在局域网里其实挺常见的,BT下载就是经典案例。但咱们今天聊的是纯前端实现,意思是完


【云计算】利用 LVS 构建集群实现负载均衡 | 集群的概念 | 单服务器性能瓶颈验证例子 | LVS 基础 | LVS 构建负载均衡集群实操步骤
王平渊2026/1/15

利用 LVS 构建集群实现负载均衡 LVS 是构建高性能、高可靠负载均衡集群的利器,其内核态转发机制和丰富的调度算法,使其成为大规模集群场景的首选方案。在实际应用中,需根据业务场景选择合适的工作模式(DR 模式为最优选择),并结合 Keepalived 实现高可用,最终解决单服务器的性能瓶颈问题。 Ⅰ. 集群(Cluster)基础 0x00 集群的概念 集群(Cluster),是一组相互独立且相互依赖、通过高速网络互联的计算机组成的计算机组,以单一模式加以管理,为用户提供统一服务。 从用户视角

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客