我可以多分区s3

时间:2018-06-07 13:05:01

标签: amazon-web-services amazon-s3 amazon-athena

我有这个数据是由其他人在S3上设置的......

数据是访问者数据...包含VisitorId,Partner,Date等列......

数据按日分区(拥有它的人,主要按日期查询)...但我也想从Athena查询它,我的大多数查询都倾向于按VisitorId分组,所以我将查询/扫描每一个,日,年,月......

我的问题是:

  • 我被告知我不能/不应该通过任何其他日期查询,我的意思是我必须在'where'条款中有'date'这是真的吗?
  • 我可以通过VisitorId进行索引(就像它是sql server中的非聚集索引一样)。
  • 我唯一的选择是重新加载数据,但这次是由VisitorId分区的吗?

请注意,现在按天划分的数据非常适合现在使用它的人...我只是碰巧需要相同的数据,但我想以不同的方式查询...

2 个答案:

答案 0 :(得分:1)

由于数据按日期分区,因此使用WHERE date BETWEEN xxx的查询将非常高效,因为只需要读取某些目录。

但是,您仍然可以按VisitorId或任何您想要的方式进行查询。只是Athena需要扫描所有分区才能找到数据。

你不能指数"列。对于这种类型的数据存储,没有这样的概念。

如果您要进行大量查询,我建议您将其转换为Parquet格式。它将提供非常有效(和低成本)的查询。与通过平面数据运行Amazon Athena查询所节省的成本相比,存储数据两次(采用不同格式)的成本最低。

请参阅:

答案 1 :(得分:0)

加入@John Rotenstein的回答,

  

我被告知我不能/不应该通过任何其他日期查询,我的意思是我   必须在'where'子句中有'date'......这是真的吗?

是的,如果您构建S3存储桶。

s3://BUCKETNAME/date_partition=2000-01-01/
s3://BUCKETNAME/date_partition=2000-01-02/
s3://BUCKETNAME/date_partition=2000-01-03/
...
s3://BUCKETNAME/date_partition=2000-06-07/
s3://BUCKETNAME/date_partition=2000-06-08/

然后,您将所有文件与桶名和分区下的给定日期对应的数据粘贴在一起。

然后编写DDL以使用此分区:

CREATE EXTERNAL TABLE somedatabase.sometable (
  VisitorId bigint,
  Partner string,
  `Date` date, 
  ...
  fieldn typen
)
PARTITIONED BY (date_partition date)
ROW FORMAT ...

正如@John Rotenstein所说,您可以在where子句中使用date_partition字段。请注意,我使用了不同的名称,因为您不能有两个具有相同名称的列。

此外,每个Athena表的软限制为20,000个分区。我检查了文档,没有找到这个限制。也许它被解除了?检查AWS Service Limits页面,我没有看到任何关于Athena表上允许的分区数量的限制。

  

我可以通过VisitorId进行索引(就好像它是sql server中的非聚集索引一样)。

是的,逻辑是相同的

  

我唯一的选择是重新加载数据,但这次是由VisitorId分区的吗?

您可以对VisitorId和日期进行分区,但您必须将正确的数据加载到正确的分区中。

s3://BUCKETNAME/date_partition=2000-01-01/visitorid_partition=1000/
s3://BUCKETNAME/date_partition=2000-01-01/visitorid_partition=2000/
s3://BUCKETNAME/date_partition=2000-01-02/visitorid_partition=1000/
s3://BUCKETNAME/date_partition=2000-01-02/visitorid_partition=2000/
...
s3://BUCKETNAME/date_partition=2000-06-07/visitorid_partition=1000/
s3://BUCKETNAME/date_partition=2000-06-08/visitorid_partition=2000/

DDL将如下编写:

CREATE EXTERNAL TABLE somedatabase.sometable (
  VisitorId bigint,
  Partner string,
  `Date` date, 
  ...
  fieldn typen
)
PARTITIONED BY (date_partition date, visitorid_partition bigint)
ROW FORMAT ...

始终请记住,压缩和列式格式将带来额外的节省。 AWS Glue可以帮助完成这些转换。

进一步阅读:

AWS Documentation » Amazon Athena » User Guide » Working with Source Data » Partitioning Data