编辑:Presto在其0.193 版本__internal_partitions__
中删除了该表,因此我建议不要在任何生产系统中使用以下部分中定义的解决方案,因为 Athena '透明地'更新了 presto 版本。我最终只使用了幼稚的查询,但也使用了本节中概述的相同的回溯技巧。它比使用table 慢大约 3 倍,但至少当 Athena 决定更新他们的 presto 版本时它不会中断。Slow aggregation queries for partition keys
SELECT max(partition_date) ...
Lack of Dynamic Filtering
__internal_partitions__
----- 原帖 -----
所以我想出了一个相当老套的方法来为大型数据集上的基于日期的分区完成此操作,因为当您只需要回顾几个分区的数据以匹配最大值时,请注意我不是 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 函数时确实做了一些预处理,因此动态过滤与使用子查询没有相同类型的问题。
因此,您可以使用 datetime 函数更改查询以限制实际最大值的回溯距离,从而限制扫描的数据量。
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
)