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”))''? –