为什么我在查询 Amazon Athena 表时收到零个记录?

2 分钟阅读
0

我在 Amazon Athena 中运行了一个 CREATE TABLE 语句,其中包含预期的列及其数据类型。当我运行查询 SELECT * FROM 表名称时,输出是Zero records returned.”。

解决方法

有一些常见原因会导致查询可能返回零个记录。根据您的用例,请参阅相关部分了解常见原因和故障排除步骤。

AWS Glue 分区

在爬网程序设置中选择了文件

如果您使用爬网程序,请确认爬网程序指向 Amazon Simple Storage Service(Amazon S3)桶而不是文件。

位置路径不正确

验证输入数据的 Amazon S3 位置路径。如果输入位置路径不正确,Athena 将返回零个记录。

位置路径中有双斜杠

Athena 不支持包含双斜杠(//)的表格位置路径。例如,以下位置路径将返回空结果:s3://doc-example-bucket/myprefix//input//

要解决此问题,将文件复制到没有双斜杠的位置。以下是复制文件的 AWS 命令行界面(AWS CLI)命令:

aws s3 cp s3://doc-example-bucket/myprefix//input// s3://doc-example-bucket/myprefix/input/ --recursive

注意: 如果在运行 AWS CLI 命令时收到错误,请确保使用最新版本的 AWS CLI

特殊字符

最佳做法是在表的列名称中只包含下划线或大写。例如,您可以将列命名为 table_name,但不能命名为 table-name以同一个 S3 前缀存储的多个表中的数据AWS Glue 爬网程序会为以同一个 S3 前缀存储的数据创建单独的表。但是,当您在 Athena 中查询这些表时,您会收到零个记录。例如,如果您的表位置与以下示例类似,您的 Athena 查询将返回零个记录:

  • s3://doc-example-bucket/table1.csv
  • s3://doc-example-bucket/table2.csv

要解决此问题,为每个表创建单独的 S3 前缀,类似于以下示例:

  • s3://doc-example-bucket/table1/table1.csv
  • s3://doc-example-bucket/table2/table2.csv

然后,运行与此示例类似的查询来更新表 table1 的位置:

ALTER TABLE table1 SET LOCATION 's3://doc-example-bucket/table1';

分区尚未加载

Athena 仅在创建表时创建元数据。数据仅在您运行查询时会被解析。如果您的表已定义分区,分区可能尚未被加载到 AWS Glue Data Catalog 或内部 Athena 数据目录中。使用 MSCK REPAIR TABLEALTER TABLE ADD PARTITION 将分区信息加载到目录中。

如果分区以 Athena 支持的格式存储,则运行 MSCK REPAIR TABLE 将分区的元数据加载到目录中。例如,如果您有一个按分区的表,Athena 预期会在 Amazon S3 路径中找到与以下示例类似的数据:

  • s3://doc-example-bucket/athena/inputdata/year=2020/data.csv
  • s3://doc-example-bucket/athena/inputdata/year=2019/data.csv
  • s3://doc-example-bucket/athena/inputdata/year=2018/data.csv

如果数据位于 Athena 预期的 Amazon S3 路径,运行与以下示例类似的命令来修复表:

CREATE EXTERNAL TABLE Employee (
    Id INT,
    Name STRING,
    Address STRING
) PARTITIONED BY (year INT)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION 's3://doc-example-bucket/athena/inputdata/';

创建表后,加载分区信息:

MSCK REPAIR TABLE Employee;

数据加载后,再次运行以下查询:

SELECT * FROM Employee;

如果分区不是以 Athena 支持的格式存储的,或者位于不同的 Amazon S3 路径,为每个分区运行 ALTER TABLE ADD PARTITION。

例如,假设您的数据位于以下示例 Amazon S3 路径:

  • s3://doc-example-bucket/athena/inputdata/2020/data.csv
  • s3://doc-example-bucket/athena/inputdata/2019/data.csv
  • s3://doc-example-bucket/athena/inputdata/2018/data.csv

使用这些路径,运行与以下示例类似的命令:

ALTER TABLE Employee ADD
    PARTITION (year=2020) LOCATION 's3://doc-example-bucket/athena/inputdata/2020/'
    PARTITION (year=2019) LOCATION 's3://doc-example-bucket/athena/inputdata/2019/'
    PARTITION (year=2018) LOCATION 's3://doc-example-bucket/athena/inputdata/2018/'

数据加载后,再次运行以下查询:

SELECT * FROM Employee;

Hive 隐藏文件

确认您的文件名不是以下划线(_)或句点(.)开头。

Athena 会将这些文件视为占位符,在您处理查询时会忽略这些文件。有关更多信息,请参阅 Athena 无法读取隐藏文件。如果您的 S3 路径中的所有文件名称均以下划线或句点开头,您将收到零个记录。

注意: 如果您的 S3 路径包含占位符以及名称以不同字符开头的文件,Athena 只会忽略占位符,会查询其他文件。因此,您可能会收到一个或多个记录。

例如:

  • s3://doc-example-bucket/athena/inputdata/_file1
  • s3://doc-example-bucket/athena/inputdata/.file2

分区投影

值不在分区投影的限定范围内

查询超出为分区投影定义的限定范围的值不会返回错误。而是返回行数为零。

例如,假设您的数据从 2020 年开始,定义为:projection.timestamp.range'='2020/01/01,NOW

如果您运行此示例查询,查询会成功完成,但返回的行数为零:

SELECT * FROM table-name WHERE timestamp = '2019/02/02'

存储模板未采用默认分区方案

如果您的 Amazon S3 文件位置未采用位置模式“.../column=value...”,您必须指定自定义 Amazon S3 分区方案。如果您未定义自定义方案,您的查询将返回零个记录。

要定义自定义 S3 分区方案,请参阅指定自定义 S3 存储位置

自定义存储模板不正确

如果您使用自定义模板,确保该模板允许 Athena 构建您的分区位置。另外,确保每个占位符和 Amazon S3 路径都以一个正斜杠结尾。

例如,假设您使用 DDL 语句 PARTITIONED BY(年份字符串)定义分区列年份,您的 S3 文件位置是 s3://doc-example-bucket/athena/inputdata/Year=2022/。 此位置将返回零个记录。将 Amazon S3 存储位置更新为:s3://doc-example-bucket/athena/inputdata/Year=${year}

分区属性

如果您有枚举、整数或日期类型的分区列,请确保正确设置分区属性。这些配置必须允许 Athena 构建与您在 Amazon S3 上的数据结构匹配的分区位置。

例如,假设您有与时间相关的数据,这些数据每天在午夜后一小时在以下位置传入:s3://doc-example-bucket/athena/inputdata/2022-01-01-01-00

在此示例中,Athena 表使用以下分区属性:

'projection.dt.format' = 'yyyy-MM-dd-HH-mm',
'projection.dt.range' = '2022-01-01-00-00,NOW',
'projection.dt.interval' = '1',
'projection.dt.interval.unit' = 'DAYS'

在示例表上运行的查询返回零个记录。这是因为此属性的预计文件位置对应于午夜 s3://doc-example-bucket/athena/inputdata/2022-01-01-00-00

要解决此问题,将属性“projection.dt.range” 设置为**“2022-01-01-01-00,NOW”**。

相关信息

在 Athena 中创建表

使用 AWS Glue 爬网程序

设置分区投影

AWS 官方
AWS 官方已更新 8 个月前