我正在使用 Athena 查询 S3 存储桶,并使用 Athena 分区投影。
这是我的桶结构:
bucket-name/node=[A-Z0-9]{4}/date={yyyy}-{MM}-{dd}/{uuid}.parquet
例如:
bucket-name/node=NODE/date=2023-10-10/123.parquet
粘合表架构:
[
{
"Name": "data",
"Type": "string"
},
{
"Name": "source_time",
"Type": "bigint"
},
{
"Name": "node",
"Type": "string",
"PartitionKey": "Partition (0)"
},
{
"Name": "date",
"Type": "date",
"PartitionKey": "Partition (1)"
}
]
胶台特性:
has_encrypted_data: false
projection.date.type: date
projection.date.format: yyyy-MM-dd
projection.date.range: 2023-01-01,2024-12-31
projection.node.type: injected
classification: parquet:
projection.enabled: true
胶台详情:
Input format: org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat
Output format: org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat
Serialization lib: org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe
我在 S3 中有以下文件:
bucket-name/node=NOD1/date=2023-10-10/FILE1.parquet
bucket-name/node=NOD1/date=2023-10-10/FILE2.parquet
bucket-name/node=NOD1/date=2023-10-11/FILE3.parquet
bucket-name/node=NOD1/date=2023-10-11/FILE4.parquet
bucket-name/node=NOD1/date=2023-10-12/FILE5.parquet
...
使用此设置: 首先,我在查询中使用节点、日期和source_time:
SELECT "$path" AS s3url
FROM "table"
WHERE node = 'NOD1'
AND date >= DATE('2023-10-10')
AND date <= DATE('2023-10-11')
AND effective_time_start >= 1696910400000
从S3日志中,我看到:
然后,我尝试仅使用节点和日期进行查询
SELECT "$path" AS s3url
FROM "table"
WHERE node = 'NOD1'
AND date >= DATE('2023-10-10')
AND date <= DATE('2023-10-11')
从S3日志中,我看到:
所以,我的问题是,当我使用不属于分区的字段时,为什么 Athena 会对同一文件进行额外的调用?
如果没有看到执行计划(您可以通过在查询上运行解释来获得执行计划),我只能给您一个有根据的猜测。
Athena(或后台的 Trino)在集群上运行,并尝试跨集群分配操作,以便为您提供更快的响应。根据镶木地板文件的大小,查询规划器可能决定将每个文件的row groups分配给不同的节点,然后并行执行过滤操作(
effective_time_start >= 1696910400000
)并最终聚合结果。这将导致集群节点多次读取文件。