我有两组人可以加入:
数据集A:每个300 KB约10000个实木复合地板文件
数据集B:每个30 MB约有50000个实木复合地板文件
我想加入两个数据集中常见的字符串列,例如“ name”。
重要的一点是,数据集A中的每一行在数据集B中都有一个匹配项。但是数据集B中包含许多其他行。
通常的联接功能需要很长时间,并且在大多数情况下会失败。所以我问是否可以进行优化?例如,按字母顺序在“名称”列上对数据集B进行分区是个好主意吗?广播联接将不起作用,因为数据集A不够小。
答案 0 :(得分:2)
如果可以在加入之前bucketize个文件,那可能更好。 否则,您需要再执行一个写步骤才能使用存储桶。
df_A.write.format('parquet')
... .bucketBy(10, 'name')
... .mode("overwrite")
... .saveAsTable('bucketed_table_A'))
df_B.write.format('parquet')
... .bucketBy(10, 'name')
... .mode("overwrite")
... .saveAsTable('bucketed_table_B'))
通过分组处理,您可以预随机化数据。 dataframa_A和datafram_B应该具有相同数量的存储桶。选择存储桶数量是一项困难的“技术”,它取决于您的数据和配置。
然后,您读取存储桶中的数据,然后将它们加入“名称”中。
spark.table('bucketed_table_A').join(
spark.table('bucketed_table_B'),
on='name',
how='left'
)
这样做,您将计算时间从连接步骤转移到写入/存储桶化步骤。但是只需执行一次,然后您就可以多次重复使用它。