过滤到pyspark数据框中的特定行的最佳方法

时间:2019-03-20 16:12:05

标签: apache-spark pyspark pyspark-sql

我有一个看似简单的问题,但我无法弄清楚。我试图基于id(主键)列过滤到特定行,因为我想在已应用转换的另一个表中对照同一id对其进行抽查。

更多细节...我有一个像这样的数据框:

|  id  | name  | age  |
| 1112 | Bob   | 54   |
| 1123 | Sue   | 23   |
| 1234 | Jim   | 37   |
| 1251 | Mel   | 58   | 
...

,除了具有〜3000MM行和〜2k列。显而易见的答案是类似df.filter('id = 1234').show()的东西。问题是我有〜300MM行,并且此查询需要 forever (就像在约20个节点的AWS EMR集群上的10-20分钟内一样)。

我知道它必须进行表扫描,但是从根本上我不理解为什么df.filter('age > 50').show()之类的内容会在约30秒内完成,而id的查询却要花这么长时间。他们俩都不必进行相同的扫描吗?

任何见识都非常欢迎。我在Linux上使用pyspark 2.4.0。

1 个答案:

答案 0 :(得分:1)

  

他们不必都进行相同的扫描吗?

这取决于数据分布。

首先show仅获取尽可能少的数据,因此只要有足够的数据来收集20行(默认值),它就可以使用LIMIT来处理单个分区。逻辑(您可以检查Spark count vs take and length以获得LIMIT行为的详细说明)。

如果1234在第一个分区上,并且您已将限制明确设置为1

df.filter('id = 1234').show(1)

时间将与另一个示例相当。

但是,如果limit小于满足谓词的值的数量,或者感兴趣的值位于其他分区中,则Spark将必须扫描所有数据。

如果要使其运行更快,则需要使用感兴趣的字段对数据进行存储(在磁盘上)或分区(在内存中),或者使用专有扩展之一(如Databricks索引)或专用存储(如不幸的那样)无效,简洁)。

但是,实际上,如果您需要快速查找,请使用适当的数据库-这是它们的目的。

相关问题