3

我一直在嘗試不同的方式來過濾類型化的數據集。事實證明,表現可能完全不同。Spark DataSet過濾器性能

該數據集是基於1.6行的數據行創建的,具有33列和4226047行。 DataSet是通過加載csv數據並映射到案例類創建的。

val df = spark.read.csv(csvFile).as[FireIncident] 

UnitId ='B02'上的過濾器應返回47980行。我測試了三種方式如下: 1)使用類型的列(〜500毫秒本地主機上)

df.where($"UnitID" === "B02").count() 

2)使用臨時表和SQL查詢(〜同選項1)

df.createOrReplaceTempView("FireIncidentsSF") 
spark.sql("SELECT * FROM FireIncidentsSF WHERE UnitID='B02'").count() 

3)使用強類型類字段(14,987ms,即30作爲慢次)

df.filter(_.UnitID.orNull == "B02").count() 

我與蟒API再次測試它,對於相同的數據集,所述定時是17046毫秒,媲美的性能Scala API選項3.

df.filter(df['UnitID'] == 'B02').count() 

有人可以瞭解3)和python API的執行方式與前兩個選項不同嗎?

回答

0

運行python時,發生的事情是,首先將代碼加載到JVM上,解釋並最終將其編譯爲字節碼。當使用Scala API時,Scala本地運行在JVM上,因此您將整個加載python代碼切割到JVM部分。

+0

具有強類型類字段的Python API和Scala API過濾器具有可比較的性能結果。你知道爲什麼選項3)比1)或2)慢30倍嗎? – YPL

4

這是因爲步驟3 here

在前兩項中,spark並不需要反序列化整個Java/Scala對象 - 它只是查看一列並繼續前進。

第三,由於您使用的是lambda函數,因此spark並不能告訴您只需要一個字段,因此它會爲每行拖出所有33個字段,以便您可以檢查一個字段領域。

我不確定爲什麼第四個這麼慢。看起來它會像第一個一樣工作。

+0

非常有見地的答案。如果你在java中使用'Dataset ''寫下了什麼:'datasetRdd.filter(r - > r。 getAs(「event_type_id」)。equals(「LOG」))''? –