要仅查询一天的数据而不让 Athena 读取所有天的所有数据,您需要创建一个 partitioned table(请看第二个示例)。分区表类似于常规表,但它们包含额外的元数据,用于描述特定分区键组合的数据所在的位置。当您运行查询并为分区键指定条件时,Athena 可以确定要读取哪些位置以及要跳过哪些位置。
如何为表配置分区键取决于数据的分区方式。在您的情况下,分区是按时间划分的,并且时间戳具有每小时粒度。您可以选择多种不同的方式来对表中的这种分区进行编码,哪种方式最好取决于您要运行的查询类型。你说你想按天查询,这是有道理的,在这种情况下会很好用。
有两种设置方式,传统方式和新方式。新方法使用了几天前刚刚发布的功能,如果您尝试查找更多示例,您可能找不到很多示例,因此我也将向您展示传统方法。
使用分区投影
使用以下 SQL 创建您的表(您必须自己填写列,因为您说您已经成功创建了一个表,并且已经使用了该表中的列 - 同时修复了 S3 位置):
CREATE EXTERNAL TABLE cszlos_firehose_data (
-- fill in your columns here
)
PARTITIONED BY (
`date` string
)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
LOCATION 's3://cszlos-data/is/here/'
TBLPROPERTIES (
"projection.enabled" = "true",
"projection.date.type" = "date",
"projection.date.range" = "2020/06/01,NOW",
"projection.date.format" = "yyyy/MM/dd",
"projection.date.interval" = "1",
"projection.date.interval.unit" = "DAYS",
"storage.location.template" = "s3://cszlos-data/is/here/${date}"
)
这将创建一个由date 分区的表(请注意,您需要在查询中引用它,例如SELECT * FROM cszlos_firehose_data WHERE "date" = …,因为它是一个保留字,如果您想避免使用另一个名称引用它,@987654328 @ 似乎很流行,还要注意它在 DDL 中用反引号和在 DML 语句中用双引号转义)。当您查询此表并为 date 指定条件时,例如… WHERE "date" = '2020/06/05',Athena 将只读取指定日期的数据。
该表使用Partition Projection,这是一项新功能,您可以将属性放在TBLPROPERTIES 部分中,告诉 Athena 您的分区键以及如何查找数据 - 这里我告诉 Athena 假设存在S3 上从 2020-06-01 到查询运行时间的数据(调整必要的开始日期),这意味着如果您指定该时间之前或“现在”之后的日期,Athena 将知道没有此类数据甚至在那些日子里都没有尝试阅读任何东西。 storage.location.template 属性告诉 Athena 在哪里可以找到特定日期的数据。如果您的查询指定了日期范围,例如… WHERE "date" > '2020/06/05'Athena 将生成每个日期(由projection.date.interval 属性控制)并读取s3://cszlos-data/is/here/2020-06-06、s3://cszlos-data/is/here/2020-06-07 等中的数据。
您可以找到完整的Kinesis Data Firehose example in the docs。它展示了如何使用分区的完整小时粒度,但您不希望这样,所以坚持上面的示例。
传统方式
传统方式与上述类似,但您必须手动添加分区以便 Athena 找到它们。首先使用以下 SQL 创建表(再次添加之前实验中的列,并修复 S3 位置):
CREATE EXTERNAL TABLE cszlos_firehose_data (
-- fill in your columns here
)
PARTITIONED BY (
`date` string
)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
LOCATION 's3://cszlos-data/is/here/'
这与上面的 SQL 完全相同,但没有表属性。如果您现在尝试对该表运行查询,您将不会得到任何结果。原因是您需要在 Athena 知道在哪里查找数据之前告诉 Athena 分区表的分区(分区表必须有一个LOCATION,但它实际上与常规表的含义不同)。
您可以通过多种不同方式添加分区,但最直接的交互式使用方式是使用ALTER TABLE ADD PARTITION。您可以在一个语句中添加多个分区,如下所示:
ALTER TABLE cszlos_firehose_data ADD
PARTITION (`date` = '2020-06-06') LOCATION 's3://cszlos-data/is/here/2020/06/06'
PARTITION (`date` = '2020-06-07') LOCATION 's3://cszlos-data/is/here/2020/06/07'
PARTITION (`date` = '2020-06-08') LOCATION 's3://cszlos-data/is/here/2020/06/08'
PARTITION (`date` = '2020-06-09') LOCATION 's3://cszlos-data/is/here/2020/06/09'
如果您开始阅读有关分区表的更多信息,您可能还会遇到MSCK REPAIR TABLE 语句作为加载分区的一种方式。不幸的是,这个命令真的很慢,而且它只适用于 Hive 风格的分区数据(例如…/year=2020/month=06/day=07/file.json)——所以你不能使用它。