Athena分区投影和混合文件模式



我想知道Athena分区投影如何处理包含具有不同字段的CSV文件的文件夹。假设我的bucket按年、月和日划分为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)

如果我为Sales创建一个表:

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语句中没有指示只对"0"进行过滤;销售;文件。当实际查询年=2020、月=01、日=01的数据时,我相信该分区中的所有Sales和Purchases文件都会被读取。我开始相信,这与通过胶水爬行器创建数据目录条目没有什么不同。它们都定义了相同的模式信息。然而,我确实相信分区投影在某种程度上是最优的。

由于Sales中的所有字段都是Purchases中字段的子集,所以我也有兴趣了解如何处理这一问题。

我注意到的另一个奇怪之处是,当我使用上面的createtable语句时,当涉及到查询时,我会做一些类似的事情

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将返回非零结果。为什么会这样?

谢谢。

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

Glue Crawler也不是解决方案,如果你把它和这个设置一起使用,它会完全一团糟。

将您的销售和采购文件放在单独的前缀中,并创建单独的表。


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

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

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

最新更新