首页/数据/数仓建模速查/AQE 自适应执行:运行时优化
湖仓与引擎63 条

AQE 自适应执行:运行时优化

AQE 在运行时根据统计信息合并小分区、转换 join 策略、处理倾斜:spark.sql.adaptive.enabled 打开后,许多手工调参可省略。

数仓建模速查数据更新于 2026-10-13

AQE 是什么

AQE(自适应查询执行)让 Spark 在运行时根据 shuffle 之后拿到的真实分区统计,回头调整执行计划:把大量小分区合并成合理大小、把 sort-merge join 改成广播 join、把异常大的分区拆成多个子任务处理。它解决的是「写 SQL 时估不准数据量」这个老问题——静态优化只能靠表统计信息猜,AQE 用实际数据修正。Spark 3.2 起 spark.sql.adaptive.enabled 默认为开启状态。

基本信息

总开关spark.sql.adaptive.enabled,Spark 3.2 起默认开启
三项主要能力合并小分区、运行时切换 join 策略、拆分倾斜分区
目标分区大小spark.sql.adaptive.advisoryPartitionSizeInBytes,默认 64MB
倾斜开关spark.sql.adaptive.skewJoin.enabled,默认开启
倾斜判据分区大小超过中位数若干倍且超过绝对阈值
相关能力动态分区裁剪,把 join 结果下推到扫描侧减少读取
局限只作用于 shuffle 之后的阶段,扫描过多与极端倾斜仍需业务侧处理

典型使用场景

  • 数据量波动大的作业:靠运行时合并小分区,省掉为每次数据量手调分区数
  • 大表关联小表:运行阶段发现小侧足够小就改走广播,避免一次多余 shuffle
  • 分区大小极度不均:把超大的倾斜分区拆成多个子任务,缩短长尾
  • 多表 join 链路:动态分区裁剪把过滤下推到扫描阶段,减少读取的数据量
  • 版本升级:升级到 3.2 及以上后,历史作业里为绕开问题加的手工参数可以逐步清理

AQE 配置示例

AQE 配置示例
spark.conf.set('spark.sql.adaptive.enabled', 'true')                      # Spark 3.2 起默认开启
spark.conf.set('spark.sql.adaptive.coalescePartitions.enabled', 'true')   # 合并小分区
spark.conf.set('spark.sql.adaptive.advisoryPartitionSizeInBytes', '128m') # 合并后的目标分区大小
spark.conf.set('spark.sql.adaptive.skewJoin.enabled', 'true')             # 拆分倾斜分区
spark.conf.set('spark.sql.adaptive.skewJoin.skewedPartitionFactor', '5')  # 超过中位数 5 倍视为倾斜
spark.conf.set('spark.sql.adaptive.localShuffleReader.enabled', 'true')   # 小数据量时本地读 shuffle
df = spark.sql('SELECT store_id, sum(pay_amt) AS amt FROM dwd_trade_order_di GROUP BY store_id')
df.explain('formatted')  # 查看 AdaptiveSparkPlan 节点确认 AQE 生效

主要子开关

子开关作用默认值
adaptive.coalescePartitions运行时合并小分区开启
adaptive.skewJoin拆分倾斜分区并处理小侧开启
adaptive.localShuffleReader小结果时本地读取 shuffle 数据开启
advisoryPartitionSizeInBytes合并后的目标分区大小64MB
开启 AQE 后,shuffle 分区数变成「初始分区数」,最终分区由运行时合并或拆分决定。初始值仍要设在合理量级,否则一开始就产生几十万个微小分区,合并本身也要付出代价。
AQE 只能优化 shuffle 之后的问题。扫描阶段读取过多、单个 key 占据大半数据的极端倾斜、以及上游数据质量问题,仍然会表现为任务超时或内存溢出。

易错点

  • 把 AQE 当成万能开关:极端倾斜与脏数据依旧导致超时,问题被误判为集群容量不足
  • 升级 Spark 后关闭了 AQE 却沿用旧参数:倾斜与小分区问题重新暴露为任务失败
  • 初始分区数设得离谱(几万甚至几十万):运行时合并开销本身就成了瓶颈
  • 期望 AQE 优化非 shuffle 阶段:扫描过多、上游小文件的问题它管不到
  • 在 Spark 2.x 上配置 AQE 参数:版本不支持,参数被静默忽略,调优结论完全失真

数据来源与参考

  • Apache Spark 官方文档:Adaptive Query Execution
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌