编辑:Presto 在他们的0.193 release 中删除了__internal_partitions__ 表,所以我建议不要在任何生产系统中使用下面Slow aggregation queries for partition keys 部分中定义的解决方案,因为Athena '透明'更新 presto 版本。我最终只使用了幼稚的SELECT max(partition_date) ... 查询,但也使用了Lack of Dynamic Filtering 部分中概述的相同回溯技巧。它比使用__internal_partitions__ 表慢了大约 3 倍,但至少在 Athena 决定更新他们的 presto 版本时它不会中断。
----- 原帖-----
因此,我想出了一个相当老套的方法来为大型数据集上的基于日期的分区完成此任务,因为当您只需要回顾几个分区的数据以匹配最大值时, ,请注意,我不能 100% 确定 information_schema.__internal_partitions__ 表的使用有多脆弱。
正如@Dain 上面提到的,确实有两个问题。第一个是 max(partition_date) 查询的聚合有多慢,第二个是 Presto 缺乏对动态过滤的支持。
分区键的慢速聚合查询
为了解决第一个问题,我使用了information_schema.__internal_partitions__ 表,它允许我快速聚合表的分区,而无需扫描文件中的数据。 (请注意,以下查询中的partition_value、partition_key 和partition_number 都是__internal_partitions__ 表的列名,与您的表的列无关)
如果您的表只有一个分区键,您可以执行以下操作:
SELECT max(partition_value) FROM information_schema.__internal_partitions__
WHERE table_schema = 'DATABASE_NAME' AND table_name = 'TABLE_NAME'
但如果您有多个分区键,则需要更多类似的东西:
SELECT max(partition_date) as latest_partition_date from (
SELECT max(case when partition_key = 'partition_date' then partition_value end) as partition_date, max(case when partition_key = 'another_partition_key' then partition_value end) as another_partition_key
FROM information_schema.__internal_partitions__
WHERE table_schema = 'DATABASE_NAME' AND table_name = 'TABLE_NAME'
GROUP BY partition_number
)
WHERE
-- ... Filter down by values for e.g. another_partition_key
)
这些查询应该运行得相当快(我的运行大约需要 1-2 秒),而无需扫描文件中的实际数据,但同样,我不确定使用这种方法是否有任何问题。
缺乏动态过滤
对于我的特定用例,我能够减轻第二个问题的最坏影响,因为我希望在从当前日期开始的有限时间内总是有一个分区(例如,我可以保证任何数据-生产或分区加载问题将在 3 天内得到解决)。事实证明,Athena 在使用 presto 的 datetime functions 时确实做了一些预处理,因此这与使用子查询的动态过滤没有相同类型的问题。
因此,您可以更改查询,以限制使用日期时间函数回溯实际最大值的距离,从而限制扫描的数据量。
SELECT * FROM "DATABASE_NAME"."TABLE_NAME"
WHERE partition_date >= cast(date '2019-06-25' - interval '3' day as varchar) -- Will only scan partitions from 3 days before '2019-06-25'
AND partition_date = (
-- Insert the partition aggregation query from above here
)