我有一个s3存储桶,其中包含基于雅典娜的分区数据。使用雅典娜,我看到表中有1040亿行。这大约有2年的数据。
我们称之为big_table
。
分区是按天,按小时进行的,因此每天07-12-2018-00,01,02 ... 24。雅典娜字段为partition_datetime
。
在我的用例中,我只需要1个月的数据,大约4亿行。
因此出现了问题-直接从以下位置加载: 1.文件
spark.load(['s3://my_bucket/my_schema/my_table_directory/07-01-2018-00/file.snappy.parquet',\
's3://my_bucket/my_schema/my_table_directory/07-01-2018-01/file.snappy.parquet' ],\
.
.
.
's3://my_bucket/my_schema/my_table_directory/07-31-2018-23/file.snappy.parquet'])
或2.通过pyspark使用SQL
df = spark.read.parquet('s3://my_bucket/my_schema/my_table_directory')
df = df.registerTempTable('tmp')
df = spark.sql("select * from my_schema.my_table_directory where partition_datetime >= '07-01-2018-00' and partition_datetime < '08-01-2018-00'")
我认为#1效率更高,因为我们只引入有关期间的数据。
2对我来说似乎效率很低,因为必须遍历整个1,040亿行(或更准确地说是partition_datetime字段)才能满足SELECT的要求。我被告知,由于延迟执行,这确实不是问题,并且所有1040亿行都没有df。我仍然说某些时候每个分区都必须由SELECT访问,因此选项1更有效。
我对此有其他意见。请鸣响
答案 0 :(得分:0)
您所说的可能是正确的,但是它效率不高,因为它永远不会扩展。如果需要三个月的数据,则不能在load命令中指定90行代码。当涉及大数据时,这不是一个好主意。您始终可以通过使用独立的Spark或YARN集群对大型数据集执行操作。
答案 1 :(得分:0)
您可以在路径中使用通配符来仅加载给定范围内的文件。
spark.read.parquet('s3://my_bucket/my_schema/my_table_directory/07-{01,02,03}-2018-*/')
或
spark.read.parquet('s3://my_bucket/my_schema/my_table_directory/07-*-2018-*/')
答案 2 :(得分:-1)
汤姆,你是对的。 #1更有效率,而且更有效。但是,您可以创建要读取的文件列表的集合,然后要求spark仅读取那些文件。
此blog可能对您的情况有所帮助。