我有一个看似简单的问题,但我无法弄清楚。我试图基于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。
答案 0 :(得分:1)
他们不必都进行相同的扫描吗?
这取决于数据分布。
首先show
仅获取尽可能少的数据,因此只要有足够的数据来收集20行(默认值),它就可以使用LIMIT
来处理单个分区。逻辑(您可以检查Spark count vs take and length以获得LIMIT
行为的详细说明)。
如果1234
在第一个分区上,并且您已将限制明确设置为1
df.filter('id = 1234').show(1)
时间将与另一个示例相当。
但是,如果limit小于满足谓词的值的数量,或者感兴趣的值位于其他分区中,则Spark将必须扫描所有数据。
如果要使其运行更快,则需要使用感兴趣的字段对数据进行存储(在磁盘上)或分区(在内存中),或者使用专有扩展之一(如Databricks索引)或专用存储(如不幸的那样)无效,简洁)。
但是,实际上,如果您需要快速查找,请使用适当的数据库-这是它们的目的。