【问题标题】:Why is Spark SQL in Spark 1.6.1 not using broadcast join in CTAS?为什么 Spark 1.6.1 中的 Spark SQL 没有在 CTAS 中使用广播连接?
【发布时间】:2016-06-13 01:26:28
【问题描述】:

我在 Spark SQL 中有一个查询,它按预期使用广播连接,因为我的表 b 小于 spark.sql.autoBroadcastJoinThreshold

但是,如果我将完全相同的选择查询放入 CTAS 查询中,那么由于某种原因它没有使用广播连接。

选择查询如下所示:

select id,name from a join b on a.name = b.bname;

对此的解释如下:

== Physical Plan ==
Project [id#1,name#2]
+- BroadcastHashJoin [name#2], [bname#3], BuildRight
   :- Scan ParquetRelation: default.a[id#1,name#2] InputPaths: ...
   +- ConvertToUnsafe
      +- HiveTableScan [bname#3], MetastoreRelation default, b, Some(b)

那么我的 CTAS 是这样的:

create table c as select id,name from a join b on a.name = b.bname; 

这个解释返回:

== Physical Plan ==
ExecutedCommand CreateTableAsSelect [Database:default}, TableName: c, InsertIntoHiveTable]
+- Project [id#1,name#2]
   +- Join Inner, Some((name#2 = bname#3))
      :- Relation[id#1,name#2] ParquetRelation: default.a
      +- MetastoreRelation default, b, Some(b)

对于作为 CTAS 查询一部分的选择查询,是否应该不使用广播连接?如果没有,有没有办法强制 CTAS 使用广播加入?

【问题讨论】:

    标签: apache-spark apache-spark-sql


    【解决方案1】:

    如果您的问题是关于 Spark 创建两个不同物理计划的原因,那么此答案将无济于事。我在 Spark 的优化器中观察到了很多敏感性,其中相同的 SQL sn-ps 会导致有意义的不同物理计划,即使这种情况的原因并不明显。

    但是,如果您的问题最终是关于如何使用广播连接执行 CTAS,那么这里有一个我使用过多次的简单解决方法:使用您喜欢的计划将查询注册为临时表(如果您是,请查看使用 SQL 控制台),然后使用 SELECT * from tmp_tbl 作为查询来提供 CTAS。

    换句话说,类似于:

    sql("select id, name from a join b on a.name = b.bname").registerTempTable("tmp_joined")
    sql("create table c as select * from tmp_joined")
    

    【讨论】:

      猜你喜欢
      • 2018-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-08
      • 2020-12-29
      • 2019-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多