Spark DataSet过滤器性能

时间:2016-12-20 19:36:44

标签: apache-spark apache-spark-sql spark-dataframe apache-spark-dataset

我一直在尝试不同的方法来过滤类型化的数据集。事实证明,性能可能完全不同。

数据集是基于1.6 GB的数据行创建的,包含33列和4226047行。通过加载csv数据并映射到案例类来创建DataSet。

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()

我使用python API再次测试它,对于相同的数据集,时间为17,046 ms,与scala API选项3的性能相当。

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

有人可以说明3)和python API的执行方式与前两个选项有何不同?

2 个答案:

答案 0 :(得分:8)

这是因为第3步here

在前两个中,spark不需要反序列化整个Java / Scala对象 - 它只是查看一列并继续前进。

第三,由于你使用的是lambda函数,spark不能告诉你只需要一个字段,所以它会为每一行拉出所有33个字段的内存,这样就可以了检查一个字段。

我不确定为什么第四个这么慢。看起来它的工作方式与第一个相同。

答案 1 :(得分:0)

当运行python时,发生的事情是首先将代码加载到JVM上,解释,然后最终编译成字节码。使用Scala API时,Scala本身在JVM上运行,因此您将整个加载python代码切换到JVM部分。