分区 Athena 表中的子查询

Subquery in partitioned Athena tables

我在 Athena 中使用分区。我有一个名为快照的分区,当我这样调用查询时:

select * from mytable where snapshot = '2020-06-25'

然后,正如预期的那样,只扫描了指定的分区,我的查询速度很快。但是,如果我使用 returns 单个日期的子查询,它是 slooow:

select * from mytable where snapshot = (select '2020-06-25')

上面实际上扫描了所有分区,而不仅仅是指定的日期,导致性能非常低。

我的问题是我可以使用子查询来指定分区并提高性能吗?我需要使用子查询来添加一些自定义逻辑,returns 一个基于某些条件的日期。

编辑:

Trino 356 能够内联此类查询,请参阅 https://github.com/trinodb/trino/issues/4231#issuecomment-845733371

较早的回答:

Presto 仍然没有像 (select '2020-06-25') 那样内联简单的子查询。 这是由 https://github.com/trinodb/trino/issues/4231 跟踪的。 因此,您不应期望 Athena 内联,因为它基于 Presto .172。

I need to use a subsquery to add some custom logic which returns a date based on some criteria.

如果您的查询要更复杂,而不是常量表达式,则无论如何都不会内联。如果 snapshot 是分区键,那么您可以利用最近添加的功能——动态分区修剪。在 https://trino.io/blog/2020/06/14/dynamic-partition-pruning.html 阅读更多内容。 这当然假设你可以选择 Presto 版本。

如果您受限于 Athena,您唯一的选择是在主查询之外(单独)评估子查询,并将其作为常量(例如文字)传回主查询。

2020 年底发布的 Athena 2.0 似乎改进了 push_down_predicate 处理以支持子查询。

这是他们来自https://docs.aws.amazon.com/athena/latest/ug/engine-versions-reference.html#engine-versions-reference-0002

的相关声明

Predicate inference and pushdown – Predicate inference and pushdown extended for queries that use a <symbol> IN <subquery> predicate.

我用我们自己的 Athena table 进行的测试表明情况确实如此。我的测试查询大致如下

SELECT *
FROM table_partitioned_by_scrape_date
WHERE scrape_date = (
  SELECT max(scrape_date) 
  FROM table_partitioned_by_scrape_date
)

从查询扫描的字节来看,我可以告诉 Athena 确实只扫描了最新的 scrape_date.

分区

此外,我还在 JOIN 子句中测试了对 push_down_predicate 的支持,其中 join_to 值是另一个查询的结果。尽管发行说明中没有提及,但显然 Athena 2.0 现在也足够智能,可以支持这种情况并且只扫描最新的 scrape_date 分区。我之前在 Athena 1.0 中测试过类似的查询,它会扫描所有分区。我的测试查询如下

WITH l as (
  SELECT max(scrape_date) as latest_scrape_date
  FROM table_partitioned_by_scrape_date
)
SELECT deckard_id
FROM table_partitioned_by_scrape_date as t
JOIN l ON t.scrape_date = l.latest_scrape_date