我没弄清楚Spark SQL连接操作实际上是如何工作的。我已阅读pretty massive explanation,但它并没有解决几个问题。
例如,您有两个保存在Spark中的数据库表(以镶木地板或任何其他格式保存)。你必须根据一些专栏加入他们:
SELECT t1.column_name_1
FROM parquet.`data/table1.parquet` as t1
LEFT JOIN parquet.`data/table2.parquet` as t2
ON t2.column_name_2 = t1.column_name_1
WHERE t2.column_name_2 is NULL
LIMIT 1
我将以sparkSession.sql(joinQuery)
table1.parquet
RDD和table2.parquet
RDD?据我所知,Spark需要一些密钥来执行改组。如果column_name_1
& column_name_2
每行有1.000.000个唯一行?我会得到多少个唯一键(分区)?我会收到多少次洗牌?table1.parquet
和table2.parquet
RDD提取到内存中? 有一个非常简单的解决方案 - 在过滤之前只有fiter DataFrames,你将把所有内容保存在RAM中。但是,我不确定这会在我的情况下表现良好。
假设过滤允许您从table1_subset1
检索table1_subset2
和table1
。现在要获得相同的连接结果,你需要做更多的连接。我的意思是:
table1 JOIN table2 = table1_subset1 JOIN table2 + table1_subset2 JOIN table2
如果我将过滤table2
:
table1 JOIN table2 = table1_subset1 JOIN table2_subset1 + table1_subset2 JOIN table2_subset1 +
table1_subset1 JOIN table2_subset2 + table1_subset2 JOIN table2_subset2
现在我必须加入大约50对巨大的表,每个表应该分成多个块(子集),比方说5个块。因此,代替50 joins
,我将获得50 * 5 * 5 = 1250
块之间的过滤和连接操作,其中每个块比原始表(RDD)小5倍。
如果我认为性能会降级很多,我是对的吗?或者Spark很聪明,可以执行相同数量的随机播放?
答案 0 :(得分:2)
1)您可以通过显式设置spark.shuffle.manager(默认为sort)在shuffle sort join或shuffle hash join之间进行选择。更多信息是here。当两个表中有很多键时,散列效率会更高。
2)为了解决这个问题,您需要在达到这一点之前过滤数据。实际上,添加前一步骤可以更快地创建表示您关心的数据子集的DataFrame。默认情况下,Spark也会溢出到磁盘,以防您无法将数据帧放入内存。对于消耗所有内存的庞大数据帧,您可以使用saveAsTable()。