为什么即使大小在 autoBroadcastJoinThreshold 下,spark (sql) 也不进行广播连接?

suj*_*jit 3 apache-spark apache-spark-sql

我正在使用 Spark 2.1.1。我有用 Spark SQL 编写的非常复杂的查询,我正在尝试对其进行优化。对于一个部分,我正在尝试使用广播连接。但即使我已经设置:

spark.sql.autoBroadcastJoinThreshold=1073741824

也就是 1GB,我看到 spark 生成的这部分执行的物理计划仍在使用 SortMergeJoin。您是否有任何见解为什么不使用广播连接,即使一侧的大小在 Spark UI -> SQL 选项卡上显示的要小得多(以 MB 为单位)?
我受影响部分的 SQL 代码部分如下所示:

-- Preceding SQL
(
SELECT  /*+ BROADCAST (a) */   -- Size of a is within broadcast threshold as per UI
     a.id,
     big.gid
 FROM
     (SELECT DISTINCT(id) AS id FROM a_par WHERE gid IS NULL) a
 JOIN
    big ON (a.id=big.id)
)
-- Succeeding SQL
Run Code Online (Sandbox Code Playgroud)

证实的 Spark UI 屏幕如下:

Con*_*ine 5

Spark 不支持自适应执行。它不会在阶段完成后根据中间统计信息(如大小、最大值、最小值等)更改执行计划。所以一旦计划在查询执行之前生成,它就不会改变。所以你会看到同样的计划。

spark不广播左表的原因是因为你的子查询缺少统计信息。我克服这个问题的方法是缓存查询结果。这有助于激发优化计划。

在您的情况下,您可以执行以下操作:

CACHE TABLE cached_a as SELECT DISTINCT(id) AS id FROM a_par WHERE gid IS NULL;

SELECT
     a.id,
     big.gid
 FROM
      cached_a
 JOIN
    big ON (a.id=big.id)
Run Code Online (Sandbox Code Playgroud)