2

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

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

然后,正如预期的那样,只扫描指定的分区并且我的查询很快。但是,如果我使用返回单个日期的子查询,它会很慢:

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

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

我的问题是我可以使用子查询来指定分区并提高性能。我需要使用子查询来添加一些自定义逻辑,该逻辑根据某些条件返回日期。

4

2 回答 2

4

编辑:

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。

我需要使用子查询来添加一些自定义逻辑,该逻辑根据某些条件返回日期。

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

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

于 2020-06-25T21:35:57.820 回答
0

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

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

谓词推理和下推——为使用 <symbol> IN <subquery> 谓词的查询扩展了谓词推理和下推。

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

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
于 2021-12-09T23:34:29.250 回答