Knowledge Center Monthly Newsletter - March 2025
Stay up to date with the latest from the Knowledge Center. See all new and updated Knowledge Center articles published in the last month and re:Post’s top contributors.
为什么我在查询 Amazon Athena 表时收到零个记录?
我在 Amazon Athena 中运行了一个 CREATE TABLE 语句,其中包含预期的列及其数据类型。当我运行查询 SELECT * FROM 表名称时,输出是Zero records returned.”。
解决方法
有一些常见原因会导致查询可能返回零个记录。根据您的用例,请参阅相关部分了解常见原因和故障排除步骤。
AWS Glue 分区
在爬网程序设置中选择了文件
如果您使用爬网程序,请确认爬网程序指向 Amazon Simple Storage Service(Amazon S3)存储桶而不是文件。此外,请确保 S3 存储桶路径不包含尾部斜杠。例如,使用 s3://doc-example-bucket/new 而不是 s3://doc-example-bucket/new/data.json。
位置路径不正确
验证输入数据的 Amazon S3 位置路径。如果输入位置路径不正确,Athena 将返回零个记录。确保 S3 存储桶路径不包含文件、尾部斜杠或通配符。例如,使用 s3://doc-example-bucket/new 而不是 s3://doc-example-bucket/new/data.json。
位置路径中有双斜杠
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 错误。此外,确保您使用的是最新版本的 AWS CLI。
特殊字符
最佳做法是在表的列名称中只包含下划线或大写。例如,您可以将列命名为 table_name,但不能命名为 table-name。
**注意:**AWS Glue 和 Athena 无法读取除下划线以外的驼峰字母、大写字母或特殊字符。
存储在同一 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 TABLE 或 ALTER 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 文件位置未采用位置模式 location pattern .../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”**。
相关信息
相关内容
- AWS 官方已更新 1 年前