如何在Spark Scala中优化广播联接?

时间:2019-02-20 15:19:42

标签: scala apache-spark

我是Spark Scala的一名新开发人员,我想通过广播连接来改进代码。

据我了解,如果我们的DataFrame大而小,那么广播联接可以优化代码。对我来说就是这样。我有第一个DF(在我的示例中为tab1),其中包含更多的30亿数据,而第二个DF仅具有900个数据。

这是我的SQL请求:

SELECT tab1.id1, regexp_extract(tab2.emp_name, ".*?(\\d+)\\)$", 1) AS city,
topo_2g3g.emp_id AS emp_id, tab1.emp_type

FROM table1 tab1

INNER JOIN table2 tab2
ON (tab1.emp_type = tab2.emp_type AND tab1.start = tab2.code)

这是我尝试使用广播联接的方法:

val tab1 = df1.filter(""" id > 100 """).as("table1")
val tab2 = df2.filter(""" id > 100 """).as("table2")

val result = tab1.join(
    broadcast(tab2)
, col("tab1.emp_type") === col("tab2.emp_type") && col("tab1.start") === col("tab2.code")
, "inner")

问题是这种方式根本没有优化。我的意思是它包含两个表的所有列,而我不需要所有这些列。我只需要其中的3个和最后一个(带有正则表达式),这根本不是最佳选择。就像,我们先生成一个很大的表,然后将其缩小为一个小表。在SQL中,我们直接得到了小表。

因此,在此步骤之后:

  • 我必须使用withColumn生成新列(使用正则表达式)
  • 应用过滤器方法选择I的3个库伦。当我在sql中立即获得它们时(我的意思是没有过滤器)。

您能帮我优化我的代码和请求吗? 预先感谢

1 个答案:

答案 0 :(得分:0)

您在进行联接之前选择所需的列

df1.select("col1", "col2").filter(""" id > 100 """).as("table1")