Spark SQL Join:实际工作原理

时间:2017-03-17 18:53:31

标签: java apache-spark apache-spark-sql spark-dataframe rdd

我没弄清楚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)

启动此查询

问题

  1. Spark会如何改变table1.parquet RDD和table2.parquet RDD?据我所知,Spark需要一些密钥来执行改组。如果column_name_1& column_name_2每行有1.000.000个唯一行?我会得到多少个唯一键(分区)?我会收到多少次洗牌?
  2. 是否可以让Spark不将整个table1.parquettable2.parquet RDD提取到内存中?
  3. 为什么我怀疑过滤

    有一个非常简单的解决方案 - 在过滤之前只有fiter DataFrames,你将把所有内容保存在RAM中。但是,我不确定这会在我的情况下表现良好。

    假设过滤允许您从table1_subset1检索table1_subset2table1。现在要获得相同的连接结果,你需要做更多的连接。我的意思是:

    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很聪明,可以执行相同数量的随机播放?

1 个答案:

答案 0 :(得分:2)

1)您可以通过显式设置spark.shuffle.manager(默认为sort)在shuffle sort join或shuffle hash join之间进行选择。更多信息是here。当两个表中有很多键时,散列效率会更高。

2)为了解决这个问题,您需要在达到这一点之前过滤数据。实际上,添加前一步骤可以更快地创建表示您关心的数据子集的DataFrame。默认情况下,Spark也会溢出到磁盘,以防您无法将数据帧放入内存。对于消耗所有内存的庞大数据帧,您可以使用saveAsTable()。