Spark - 选择WHERE还是过滤?

90

使用where子句进行选择和在Spark中进行过滤有什么区别?
是否存在某些情况,其中一个比另一个更合适?

何时使用哪种方法?

DataFrame newdf = df.select(df.col("*")).where(df.col("somecol").leq(10))

什么时候是

DataFrame newdf = df.select(df.col("*")).filter("somecol <= 10")

更合适吗?

2个回答

139
根据Spark文档,"where()filter()的别名"。 filter(condition) 通过给定的条件过滤行。where()filter()的别名。 参数: condition - types.BooleanType类型的Column或SQL表达式字符串。
>>> df.filter(df.age > 3).collect()
[Row(age=5, name=u'Bob')]
>>> df.where(df.age == 2).collect()
[Row(age=2, name=u'Alice')]

>>> df.filter("age > 3").collect()
[Row(age=5, name=u'Bob')]
>>> df.where("age = 2").collect()
[Row(age=2, name=u'Alice')]

7
自你上次回答以来已经有一段时间了,但是使用Column或使用SQL字符串进行过滤是否存在显著的性能差异? - Megan
2
@Megan - 在过滤时,使用列或字符串没有显著的性能差异。它们都生成相同的物理计划,因此执行方式也相同。请参阅我的答案以获取更多详细信息。 - Powers

18

正如Yaron所提到的,wherefilter之间没有任何区别。

filter是一个重载方法,它接受列或字符串参数。无论您使用哪种语法,性能都是相同的。

filter overloaded method

我们可以使用explain()来查看所有不同的过滤语法生成相同的物理计划。假设有一个带有person_nameperson_country列的数据集。以下所有代码片段将返回下面相同的物理计划:

df.where("person_country = 'Cuba'").explain()
df.where($"person_country" === "Cuba").explain()
df.where('person_country === "Cuba").explain()
df.filter("person_country = 'Cuba'").explain()

所有这些都返回此物理计划:

== Physical Plan ==
*(1) Project [person_name#152, person_country#153]
+- *(1) Filter (isnotnull(person_country#153) && (person_country#153 = Cuba))
   +- *(1) FileScan csv [person_name#152,person_country#153] Batched: false, Format: CSV, Location: InMemoryFileIndex[file:/Users/matthewpowers/Documents/code/my_apps/mungingdata/spark2/src/test/re..., PartitionFilters: [], PushedFilters: [IsNotNull(person_country), EqualTo(person_country,Cuba)], ReadSchema: struct<person_name:string,person_country:string>

语法不会改变过滤器在底层的执行方式,但是查询执行的文件格式/数据库会有所不同。Spark将在Postgres(支持谓词下推过滤)、Parquet(列修剪)和CSV文件上以不同的方式执行相同的查询。此处了解更多细节。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接