Apache spark Spark Join最佳匹配效率问题
我有两个数据帧:Apache spark Spark Join最佳匹配效率问题,apache-spark,join,pyspark,Apache Spark,Join,Pyspark,我有两个数据帧: df_1拥有约5亿条记录和约100列 df_2有约5000万条记录和4列 我需要将df_1与df_2左连接,其中两列精确匹配,第三列最佳匹配。所谓最佳匹配,我的意思是有一个:从左到右的关系很多,但我只想在长度上得到右侧的最佳匹配 e、 g 因此,当我精确地匹配col1和col2以及col3所包含字符串的最佳匹配时,联接的预期结果是: col1 col2 col3 col4 ------------------------------- a b
拥有约5亿条记录和约100列df_1
有约5000万条记录和4列df_2
df_1
与df_2
左连接,其中两列精确匹配,第三列最佳匹配。所谓最佳匹配,我的意思是有一个:从左到右的关系很多,但我只想在长度上得到右侧的最佳匹配
e、 g
因此,当我精确地匹配col1
和col2
以及col3
所包含字符串的最佳匹配时,联接的预期结果是:
col1 col2 col3 col4
-------------------------------
a b abcde 150
以下几点对我不利:
- 左侧的
长度通常在10到15个字符之间,右侧的长度可以从1个字符到9个字符不等col3
和df_1
在df_2
col3
- 广播
(由于太大而无法广播)df_2
- 在
和col1
上精确连接,并在col1
上使用col3
类似的
(糟糕)
- 将
中的df_2
上的值分解出来,尝试与歪斜作斗争(改善但仍然缓慢)col3
- 保留数据并循环右侧的每个长度,并在
、col1
和col2
的串联上精确连接(其中左侧的串联是col3
的子串)(改进但仍然缓慢)col3
使用spark进行此连接最有效的方法是什么?更好的选择是在连接之前减小数据大小(我们无法消除连接)。我们可以减少以下费用: 首先,加载数据
scala> import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.expressions.Window
scala> import org.apache.spark.sql.functions._
import org.apache.spark.sql.functions._
scala> df1.show
+---+---+-----+
| c1| c2| c3|
+---+---+-----+
| a| b|abcde|
| c| d| fd|
+---+---+-----+
scala> df2.show
+---+---+----+---+
| c1| c2| c3| c4|
+---+---+----+---+
| a| b| a| 90|
| a| b| abd|100|
| a| b|abcd|150|
| c| d|wewe| 79|
+---+---+----+---+
现在,我们需要在加入之前减少df2的大小(这将减少加入所需的时间,因为数据大小比较少),使用窗口函数并找出两列的最大值
scala> df2.withColumn("len", length($"c3")).withColumn("res", row_number().over(wind1)).filter($"res" === 1).withColumn("res2", row_number().over(wind2)).filter($"res2"=== 1).select("c1", "c2", "c3", "c4").show()
+---+---+----+---+
| c1| c2| c3| c4|
+---+---+----+---+
| c| d|wewe| 79|
| a| b|abcd|150|
+---+---+----+---+
尝试的事项:
1> 您可以加入这个简化的数据帧并应用您正在使用的逻辑
2> 尝试使用列(“c4”,lit(0)).union(df2)执行uniondf1,然后应用上述逻辑
希望这有帮助,在df1中,你需要一个更大的字符串&从df2中,你需要最大的数字,或者从两个数据帧中,你需要一个更大的串联和更大的数字??因此在df1中,我在col3中有一个字符串,我需要在d2 col3中找到最长的匹配,以带回COL4。请你解释一下,本质上,df1是我模型的主要输出,df2是一个查找表,使我能够通过连接其他3列返回col4
,以便以后使用。第3列具有可变长度(每行一个),我需要返回对应的col4,以匹配COL3中最长的值。您是否根据col_4值选择第三行,因为它在其他a和b组合(150)中最高?
scala> import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.expressions.Window
scala> import org.apache.spark.sql.functions._
import org.apache.spark.sql.functions._
scala> df1.show
+---+---+-----+
| c1| c2| c3|
+---+---+-----+
| a| b|abcde|
| c| d| fd|
+---+---+-----+
scala> df2.show
+---+---+----+---+
| c1| c2| c3| c4|
+---+---+----+---+
| a| b| a| 90|
| a| b| abd|100|
| a| b|abcd|150|
| c| d|wewe| 79|
+---+---+----+---+
scala> df2.withColumn("len", length($"c3")).withColumn("res", row_number().over(wind1)).filter($"res" === 1).withColumn("res2", row_number().over(wind2)).filter($"res2"=== 1).select("c1", "c2", "c3", "c4").show()
+---+---+----+---+
| c1| c2| c3| c4|
+---+---+----+---+
| c| d|wewe| 79|
| a| b|abcd|150|
+---+---+----+---+