雅典娜分区投影和混合文件架构

时间:2020-10-08 01:34:51

标签: amazon-athena

我想知道Athena分区投影如何处理包含具有不同字段的CSV文件的文件夹。假设我的存储桶按年,月和日划分为s3:// SalesPurchases / {year} / {month} / {day}。在每个15分钟的间隔内,我会生成两个文件,描述在该间隔内进行的销售和购买。例如,文件名将为Sales-15min-03:00.csv,表示该文件是在凌晨3点生成的,并具有前15分钟的更新时间。这些文件包含以下字段:

Sales: id, description, amount - (all strings)
Purchases: id, description, vendor, amount - (all strings)

如果我创建用于销售的表:

CREATE EXTERNAL TABLE sales_data (
id string,
description string,
amount string
)
PARTITIONED BY (
  `year` string,
  `month` string,
  `day` string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
LOCATION 's3://SalesPurchases/'
TBLPROPERTIES (
  "skip.header.line.count" = "1",
  "projection.enabled" = "true",
  "projection.year.type" = "integer",
  "projection.year.range" = "2020,2021",
  "projection.month.type" = "integer",
  "projection.month.range" = "01,12",
  "projection.day.type" = "integer",
  "projection.day.range" = "01,31",
  "storage.location.template" = "s3://SalesPurchases/${year}/${month}/${day}"
)

我只是想知道这种方法的效率。此CREATE语句中没有指示仅过滤“销售”文件。当需要实际查询year = 2020,month = 01,day = 01的数据时,我相信将读取该分区中的所有Sales和Purchase文件。我开始相信这与通过粘合搜寻器创建数据目录条目没有什么不同。它们都将定义相同的架构信息。但是,我确实相信分区投影在某种程度上会更理想。

由于“销售”中的所有字段都是“购买”中字段的子集,所以我也有兴趣了解如何处理此字段。

我注意到的另一个奇怪之处是,当我使用上面的create table语句时,到了查询的时候,我做了类似的事情

select * from sales_data limit 10

select count(*) from sales_data

我得到零结果。我必须在查询中特别添加其他过滤器,以获取有意义的信息,例如

select * from sales_data where year = '2020' and month = '01' and day = '01' limit 10

这与分区投影很奇怪吗?但是,使用搜寻器生成架构信息时并非如此。在这种情况下,select * from sales_data limit 10将返回非零结果。为什么会这样?

谢谢。

1 个答案:

答案 0 :(得分:2)

Athena要求表中的所有文件都具有相同的架构。运行查询时,它将列出并处理表LOCATION(或表分区的LOCATION)给定的S3前缀中的所有文件。没有办法告诉它按名称过滤文件,它将始终处理所有文件。无论您是否使用分区投影,此方法都相同。

Glue Crawler也不是解决方案,如果与该设置一起使用,它将完全混乱。

将销售和购买文件放入单独的前缀并创建单独的表。


查询最终结果为零的原因是,您需要将月份和日期分区键配置为零填充:

"projection.month.digits" = "2"
"projection.day.digits" = "2"

令人困惑的是,该范围允许零前缀的值,即使它实际上没有将范围配置为零前缀。