簡體   English   中英

DataFrame操作的怪異行為

[英]Weird behavior of DataFrame operations

考慮一下代碼:

val df1 = spark.table("t1").filter(col("c1")=== lit(127))
val df2 = spark.sql("select x,y,z from  ORCtable")
val df3 = df1.join(df2.toDF(df2.columns.map(_ + "_R"): _*),
  trim(upper(coalesce(col("y_R"), lit("")))) === trim(upper(coalesce(col("a"), lit("")))), "leftouter")
df3.select($"y_R",$"z_R").show(500,false)

這將產生警告WARN TaskMemoryManager: Failed to allocate a page (2097152 bytes), try again. 代碼失敗java.lang.OutOfMemoryError: GC overhead limit exceeded

但是,如果我運行以下代碼:

val df1 = spark.table("t1").filter(col("c1")=== lit(127))
val df2 = spark.sql("select x,y,z from  ORCtable limit 2000000")//only difference here
//ORC table has 1651343 rows so doesn't exceed limit 2000000
val df3 = df1.join(df2.toDF(df2.columns.map(_ + "_R"): _*),
  trim(upper(coalesce(col("y_R"), lit("")))) === trim(upper(coalesce(col("a"), lit("")))), "leftouter")
df3.select($"y_R",$"z_R").show(500,false)

這將產生正確的輸出。 我茫然為什么會發生這種情況以及發生什么變化。 有人可以幫忙嗎?

回答我自己的問題:生成相同dataframe的兩種方式的Spark physical execution plan是不同的,可以通過調用.explain()方法進行檢查。

第一種方法使用broadcast-hash join ,這會導致java.lang.OutOfMemoryError: GC overhead limit exceededjava.lang.OutOfMemoryError: GC overhead limit exceeded而第二種方法運行了sort-merge join ,該sort-merge join通常較慢,但不會對垃圾回收造成太大的負擔。

物理執行計划中的這種差異是由df2 dataframe上的附加filter操作引起的。

暫無
暫無

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

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