[英]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 的所有行放在同一分區中。
要解決此問題,您可以使用以下模式:
Table1
dataframe between null ids dataframe and not null ids dataframeTable2
Table2
的列添加到null ids dataframe您可以在下面找到此模式的代碼翻譯:
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
,或者按照您的建議繼續,向Table1
和Table2
添加一個加鹽列,並在您的連接表達式中使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.