Athena 在某些查询中忽略 LIMIT

Posted

技术标签:

【中文标题】Athena 在某些查询中忽略 LIMIT【英文标题】:Athena ignore LIMIT in some queries 【发布时间】:2022-01-09 22:59:04 【问题描述】:

我有一张有很多分区的表(我们正在努力减少分区)

当我查询时:

SELECT * FROM mytable LIMIT 10

我明白了:

“HIVE_EXCEEDED_PARTITION_LIMIT:对表 'mytable' 的查询可能读取超过 1000000 个分区”

为什么查询的“LIMIT 10”部分不足以让 Athena 在不读取超过 1 或 3 个分区的情况下返回结果?

回答: 在查询计划阶段,Athena 会尝试列出回答查询可能需要的所有分区。 由于 Athena 不知道哪些分区实际包含数据(不是空分区),它会将所有分区添加到列表中。

【问题讨论】:

【参考方案1】:

Athena 计划一个查询,然后执行它。在规划期间,它会列出分区以及这些分区中的所有文件。但是,它对文件、它们包含多少条记录等一无所知。

当您说LIMIT 10 时,您是在告诉 Athena 您希望结果中最多有 10 条记录,并且由于您没有任何分组或排序,因此您需要 10 条任意记录。

但是,在规划阶段,Athena 无法知道哪些分区中有文件,以及需要读取多少个文件才能找到 10 条记录。如果不列出分区位置,它就无法知道它们并非都是空的,如果不读取文件,它也无法知道它们也不都是空的。

因此,Athena 首先必须获取分区列表,然后列出每个分区在 S3 上的位置,即使您说您只想要 10 条任意记录。

在这种情况下,Athena 短路的分区太多,并说您可能不是有意运行这种查询。如果表的分区较少,Athena 将执行查询,每个工作人员将尽可能少地读取以返回 10 条记录然后停止 - 但每个工作人员会产生 10 条记录,因为工作人员不能假设其他工作人员会返回任何记录.最后,coordinator会从所有worker的所有结果中选出10条记录作为最终结果返回。

【讨论】:

【参考方案2】:

如果我没记错的话,限制仅适用于显示操作。所以查询仍然会读取所有内容,但只显示 10 条记录。 尝试使用 where 条件限制数据,应该可以解决问题

【讨论】:

我认为这不太可能,如果查询会读取所有数据然后只返回前 10 条记录,那将是非常低效的。更有可能的是,查询规划器无法可靠地确定需要读取多少个分区才能满足查询,从而引发此消息。 @NNM 您能否提供此信息的任何来源(“限制仅在展示时有效”)?我没有在 AWS 文档中找到该信息。还建议使用 where 条件。【参考方案3】:

我认为 Athena 的工作人员尝试读取最大分区数(相对于表的分区大小)以获取随机数据块并在查询完成时停止(在您的情况下,这是限制的规范)。

在您的情况下,由于涉及的分区太多,它甚至没有开始执行上述过程。因此,如果 Athena 没有计划您的随机数据选择查询,您必须明确计划并将其交给执行引擎。

类似:

select * from mytable 
where (
   partition_column in (
      select partition_column from mytable limit cast(10 * rand() as integer)
   )
)
limit 100

【讨论】:

以上是关于Athena 在某些查询中忽略 LIMIT的主要内容,如果未能解决你的问题,请参考以下文章

Redshift 查询忽略 LIMIT 子句

Athena Query - “NOT IN” 性能缓慢

AWS Athena 上的偏移量

AWS Athena (Presto) 偏移支持

我可以从存储在 S3 中的 sql 文件运行 Athena 查询吗

在 AWS Athena 中清理 SQL 查询参数