簡體   English   中英

PySpark 優化兩個大表的左連接

[英]PySpark optimize left join of two big tables

我在 Databricks 上使用 PySpark 的最新版本。 我有兩個表,每個表的大小約為 25-30GB。 我想分別在“id”和“id_key”列加入 Table1 和 Table2。 我可以使用下面的命令來做到這一點,但是當我運行我的 spark 作業時,連接是傾斜的,導致 +95% 的數據在一個執行器上,這使得作業需要永遠完成。 當我在轉換數據后嘗試加載數據時,就會發生這種情況。

表 1 共有 13 列,其中“id”列有很多 null 值和一些實際的 id 值。

Table2 共有 3 列,其中“id_key”具有所有可能的 id 值,每個值出現一次。

我嘗試廣播,但由於表非常大,運行作業時出現 OutOfMemory 錯誤

Table1.join(Table2, Table1.id == Table2.id_key, "left")

我正在考慮加鹽,但不確定如何解決這個問題,或者它是否是正確的解決方案。

據我了解您的問題,我猜 Spark 必須在連接分區期間將Table1中具有null id 的所有行放在同一分區中。

要解決此問題,您可以使用以下模式:

  • split Table1 dataframe between null ids dataframe and not null ids dataframe
  • 加入你的不是 null ids dataframeTable2
  • 將具有 null 值的表Table2的列添加到null ids dataframe
  • 聯合獲得的不是 null ids dataframenull ids Z6A8064B5DF479455507DZC553

您可以在下面找到此模式的代碼翻譯:

from pyspark.sql import functions as F

Table1_with_null_ids = Table1.filter(F.col('id').isNull())
Table1_with_not_null_ids = Table1.filter(F.col('id').isNotNull())

Table1_with_not_null_ids_joined = Table1_with_not_null_ids.join(
  Table2, 
  Table1_with_not_null_ids.id == Table2.id_key, 
  'left'
)

Table1_with_null_ids_joined = Table1_with_null_ids \
  .withColumn('id_key', F.lit(None)) \
  .withColumn('table2_column2', F.lit(None)) \
  .withColumn('table2_column3', F.lit(None))

Table1_joined = Table1_with_not_null_ids_joined.unionByName(Table1_with_null_ids_joined)

它避免了手動加鹽,當您加入Table2時,它可能會提高性能,而Table1端的行數要少得多

但是,當您在同一個Table1上執行兩次filter時,您需要計算輸入Table1兩次。 如果計算輸入Table1是一個昂貴的過程,您可以在雙重過濾之前緩存Table1 ,或者按照您的建議繼續,向Table1Table2添加一個加鹽列,並在您的連接表達式中使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM