Athena 查询非常慢

roa*_*rkz 3 amazon-s3 amazon-web-services parquet amazon-athena aws-glue

我在 S3 中存储 400,000 个镶木地板文件,这些文件根据唯一 ID(例如 412812)进行分区。这些文件的数据大小从 25kb 到 250kb 不等。然后我想使用 Athena 查询数据。就像这样,

Select * 
From Table 
where id in (412812, 412813, 412814)
Run Code Online (Sandbox Code Playgroud)

该查询比预期慢得多。我希望能够搜索任何一组 ID 并获得快速响应。我相信它很慢是因为 Athena 必须搜索整个胶水目录以查找正确的文件(即对文件进行完整扫描)。

下面的查询速度非常快。不到一秒钟。

Select * 
From Table 
where id = 412812
Run Code Online (Sandbox Code Playgroud)

表上启用了partition.filtering。我尝试向表中添加与分区相同的索引,但它没有加快任何速度。

我的方法或表配置是否有问题,可以使此过程更快?

Joh*_*ein 7

您的基本问题是您有太多文件和太多分区

虽然 Amazon Athena 确实并行运行,但它可以同时处理的文件数量受到限制。另外,每个额外的文件都会增加列出、打开等的开销。

此外,在每个分区中只放置一个文件会大大增加处理如此多分区的开销,并且可能对提高系统效率产生反作用。

我不知道您实际如何使用数据,但根据您的描述,我建议您创建一个新表,即bucketed_byid,而不是分区表:

CREATE TABLE new_table
WITH (
 format = 'PARQUET',
 parquet_compression = 'SNAPPY',
 external_location = 's3://bucket/new_location/',
 bucketed_by = ARRAY['id']
)
AS SELECT * FROM existing_table
Run Code Online (Sandbox Code Playgroud)

让 Athena 创建任意数量的文件 - 它将根据数据量进行优化。更重要的是,它将创建更大的文件,使其能够更有效地运行。

请参阅:分桶与分区 - Amazon Athena

一般来说,当您可以将数据划分为一些主要子集(例如按国家/地区、州或代表相当大数据块的内容)时,分区就非常有用,而分桶则更适合具有相对不常见值的字段(例如用户ID)。分桶将创建多个文件,Athena 会足够聪明,知道哪些文件包含您想要的 ID。但是,它不会根据这些值划分为子目录。

创建这个新表将大大减少 Amazon Athena 需要为每个查询处理的文件数量,这将使您的查询运行速度更快