Spark中内连接的分区数如何计算?为何结果不是两表分区数乘积
Spark Join操作分区计算逻辑答疑
一、Spark执行连接操作时的分区计算规则
Spark会先根据两张表的大小、Join条件类型自动选择Join策略,不同策略的分区处理逻辑完全不同:
- 广播Hash Join(Broadcast Hash Join)
这是小表和大表Join的默认策略,当其中一张表的大小小于spark.sql.autoBroadcastJoinThreshold(默认值为10MB)时触发:Spark会将小表全量广播到所有Executor节点,大表不需要做shuffle,直接在每个分区和广播的小表做本地匹配。这种场景下,Join结果的分区数完全等于大表的原始分区数。
你遇到的结果为160的情况,大概率是只有9个分区的df_A被判定为小表触发了广播Join,结果直接复用了大表df_B的160个分区。 - 排序合并Join(Sort Merge Join)
这是大表之间等值Join的默认策略:如果两张表都未按Join key预分区,Spark会先将两张表都按照Join key做shuffle,shuffle后的分区数默认由配置spark.sql.shuffle.partitions控制(默认值为200),Join结果的分区数和该配置一致。如果其中一张表已经按Join key完成了分区,Spark会优先复用该表的分区减少shuffle开销,结果分区数和复用的表分区数一致。 - 笛卡尔积Join(Cross Join)
只有当Join没有匹配条件、两张表的所有行两两组合时才会触发,这种场景下会将两张表的分区两两组合计算,结果分区数为两张表的分区数乘积,也就是你提到的9 * 160 = 1440。
二、为什么结果分区数不是1440
9 * 160的分区数仅适用于无匹配条件的笛卡尔积Join场景,你的业务使用的是带ON条件的内连接,不需要将两张表的所有分区两两匹配,自然不会触发笛卡尔积的分区计算规则。
你场景中得到160的结果,最常见的原因就是df_A体积过小触发了广播Join,直接复用了大表df_B的160个分区,没有产生额外的shuffle分区。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

