Apache spark 如何通过在已知密钥上加入数据帧来提高spark性能

Apache spark 如何通过在已知密钥上加入数据帧来提高spark性能,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,我有两个大拼花Dataframes,我想在userId上加入它们 我应该怎样做才能获得高性能: 我是否应该修改编写这些文件的代码,以便: 用户ID上的分区(非常稀疏) 用户ID的前N个字符上的分区 (好的,如果数据已经在同一个键上进行了分区,那么连接将在不进行洗牌的情况下进行) 在读取端,使用RDD或DataFrame更好吗?您可以在保存到拼花文件之前执行bucketBy操作 val NUM_BUCKETS = 20 df1.write.mode(SaveMode.Overwrite).bu

我有两个大拼花
Dataframe
s,我想在
userId
上加入它们

我应该怎样做才能获得高性能:

我是否应该修改编写这些文件的代码,以便:

  • 用户ID上的分区(非常稀疏)
  • 用户ID的前N个字符上的分区 (好的,如果数据已经在同一个键上进行了分区,那么连接将在不进行洗牌的情况下进行)

在读取端,使用
RDD
DataFrame
更好吗?

您可以在保存到拼花文件之前执行bucketBy操作

val NUM_BUCKETS = 20
df1.write.mode(SaveMode.Overwrite).bucketBy(NUM_BUCKETS, "userId").saveAsTable("bucketed_large_table_1")
df2.write.mode(SaveMode.Overwrite).bucketBy(NUM_BUCKETS, "userId").saveAsTable("bucketed_large_table_2")
spark.sql("select * from a join b on a.num1 = b.num2").collect()
这样做可以防止在执行join操作时出现混乱


请记住,要做到这一点,您需要使用.enableHiveSupport启用配置单元,因为“保存到拼花地板”操作目前不支持bucketBy方法。

RDD或DataFrame取决于您希望对数据执行的操作。数据帧在RDD中进行了优化,但有些操作在RDD中执行得更好,而大多数操作在DataFrame中执行得更好。关于partitionBy,你完全正确。您可以使用HashPartitioner。但是有一个小问题,即,
partitionBy
首先对数据进行排序,然后保存数据。它会使写入速度变慢,但读取/连接速度会变快。因此,在使用
partitionBy
@himanshuIIITian之前要小心。请注意,如果在调用
write
之前调用
repartion(colX,colY)
,可以大大加快
partitionBy(colX,colY)
的性能。因此
df.repartion(colX,colY).write.partitionBy(colX,colY)
比调用
df.write.partitionBy(colX,colyY)
:)@GlennieHellesSindholt要快得多,我试过了,发现
repartition
创建的分区数是200(默认值)。而数据帧中唯一值的数量只有一个。这实际上减慢了写入存储器的速度。为此,我已经在stackoverflow上发布了一个问题-@Yann Moisan您在每个文件中的用户ID都有高重复性吗?