Ongoing service disruptions
For the most recent update on ongoing service disruptions affecting the AWS Middle East (UAE) Region (ME-CENTRAL-1), refer to the AWS Health Dashboard. For information on AWS Service migration, see How do I migrate my services to another region?
为什么我在查询 Athena 表时收到零个记录?
我在 Amazon Athena 中运行了一个 CREATE TABLE 语句,其中包含预期的列及其数据类型。但是,当我运行 SELECT * FROM 表名查询时,我收到“没有返回的记录”的输出。
解决方法
**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
SELECT * FROM 表名查询返回零个记录的原因有很多。根据您的使用案例,请参阅相关部分了解常见原因和故障排除步骤。
对 AWS Glue 分区进行故障排除
检查爬网程序设置
如果您使用爬网程序,请确认爬网程序指向 Amazon Simple Storage Service (Amazon S3) 存储桶而不是特定文件。例如,使用 s3://amzn-s3-demo-bucket/new 而不是 s3://amzn-s3-demo-bucket/new/data.json。
使用正确的 LOCATION 路径
验证输入数据的 Amazon S3 LOCATION 路径是否正确。此外,确保 S3 存储桶路径不包含文件或通配符。例如,使用 LOCATION s3://amzn-s3-demo-bucket/new 而不是 s3://amzn-s3-demo-bucket/new/data.json。
在 LOCATION 路径中使用单斜杠
在 Athena 中,不能使用包含双斜杠 (//) 的表位置路径。例如,以下 LOCATION 路径将返回空结果:s3://amzn-s3-demo-bucket/myprefix//input//
要将文件复制到没有双斜杠的位置,请运行以下 cp AWS CLI 命令:
aws s3 cp s3://amzn-s3-demo-bucket/myprefix//input// s3://amzn-s3-demo-bucket/myprefix/input/ --recursive
**注意:**请将 amzn-s3-demo-bucket/myprefix//input// 替换为您当前的表位置路径,并将 amzn-s3-demo-bucket/myprefix/input/ 替换为新的表位置路径。
最佳做法是在表的列名称中只包含下划线或大写。例如,您可以将列命名为 table_name,但不能命名为 table-name。
**注意:**AWS Glue 和 Athena 无法读取除下划线以外的驼峰字母、大写字母或特殊字符。
为每个表创建 Amazon S3 前缀
AWS Glue 爬网程序为存储在同一 Amazon S3 前缀中的数据创建单独的表。但是,当您在 Athena 中查询这些表时,您会收到零个记录。例如,如果您的表位置与以下示例类似,您的 Athena 查询将返回零个记录:
- s3://amzn-s3-demo-bucket/table1.csv
- s3://amzn-s3-demo-bucket/table2.csv
要解决此问题,请为每个表创建单独的 Amazon S3 前缀,类似于以下示例:
- s3://amzn-s3-demo-bucket/table1/table1.csv
- s3://amzn-s3-demo-bucket/table2/table2.csv
然后,运行以下查询来更新表的位置:
ALTER TABLE table1 SET LOCATION 's3://amzn-s3-demo-bucket/table1';
**注意:**请将 amzn-s3-demo-bucket 替换为您的存储桶名称,并将 table1 替换为您的表名。
加载分区
Athena 仅在创建表时创建元数据。数据仅在运行查询时会被解析。如果您的表已定义分区,则 AWS Glue Data Catalog 或内部 Athena 数据目录可能尚未加载分区。
如果 Athena 支持您的分区格式,则运行 MSCK REPAIR TABLE 将分区的元数据加载到目录中。例如,您有一个按年分区的表。在这种情况下,Athena 预期会在 Amazon S3 路径中找到与以下示例类似的数据:
- s3://amzn-s3-demo-bucket/athena/inputdata/year=2020/data.csv
- s3://amzn-s3-demo-bucket/athena/inputdata/year=2019/data.csv
- s3://amzn-s3-demo-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://amzn-s3-demo-bucket/athena/inputdata/';
Athena 创建表后,运行以下命令加载分区信息:
MSCK REPAIR TABLE Employee;
Athena 加载数据后,再次运行以下查询:
SELECT * FROM Employee;
如果 Athena 不支持您的分区格式,或者分区位于不同的 Amazon S3 路径中,则为每个分区运行 ALTER TABLE ADD PARTITION。
例如,您的数据位于以下示例 Amazon S3 路径:
- s3://amzn-s3-demo-bucket/athena/inputdata/2020/data.csv
- s3://amzn-s3-demo-bucket/athena/inputdata/2019/data.csv
- s3://amzn-s3-demo-bucket/athena/inputdata/2018/data.csv
对于上述路径,运行与以下示例类似的命令:
ALTER TABLE Employee ADD PARTITION (year=2020) LOCATION 's3://amzn-s3-demo-bucket/athena/inputdata/2020/' PARTITION (year=2019) LOCATION 's3://amzn-s3-demo-bucket/athena/inputdata/2019/' PARTITION (year=2018) LOCATION 's3://amzn-s3-demo-bucket/athena/inputdata/2018/'
Athena 加载数据后,再次运行以下查询:
SELECT * FROM Employee;
检查文件名
确认您的文件名不是以下划线或句点开头。
在处理查询时,Athena 会将这些文件视为占位符并忽略这些文件。如果您的 Amazon S3 路径中的所有文件名称均以下划线或句点开头,您将收到零个记录。
例如,如果您使用 Amazon S3 路径中的以下文件处理查询,则收到的记录为零:
- s3://amzn-s3-demo-bucket/athena/inputdata/_file1
- s3://amzn-s3-demo-bucket/athena/inputdata/.file2
**注意:**如果您的 Amazon S3 路径包含占位符及以不同字符开头的文件,则 Athena 仅忽略占位符并查询其他文件。因此,您可能会收到一个或多个记录。
对分区投影进行故障排除
确认您的值在范围内
如果您的值超出为分区投影定义的限定范围,则查询返回的行数为零。
例如,您的数据从 2020 年开始,并且您将其定义为:projection.timestamp.range'='2020/01/01,NOW
如果您运行以下查询,则查询会成功完成,但返回的行数为零:
SELECT * FROM table-name WHERE timestamp = '2019/02/02'
验证存储模板的分区方案
如果您的 Amazon S3 存储位置未采用 .../column=value... 位置模式,则必须指定自定义 Amazon S3 分区方案。如果您未定义自定义方案,您的查询将返回零个记录。
使用正确的自定义存储模板
如果您使用自定义模板,请确保该模板允许 Athena 构建您的分区位置。同时,确保每个占位符和 Amazon S3 路径都以单个正斜杠结尾。
例如,您使用 PARTITIONED BY (year string) 数据定义语言 (DDL) 语句定义了年分区列,而存储位置为 s3://amzn-s3-demo-bucket/athena/inputdata/Year=2022/。此位置将返回零个记录。要解决此问题,请将存储位置更新为 s3://amzn-s3-demo-bucket/athena/inputdata/Year=${year}。
验证分区属性
如果您的分区列类型为 enum、integer、date 或 injected,请确保正确配置分区属性。这些配置必须允许 Athena 构建与您在 Amazon S3 上的数据结构匹配的分区位置。
例如,您的时间相关数据每天在午夜后 1 小时传入 s3://amzn-s3-demo-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://amzn-s3-demo-bucket/athena/inputdata/2022-01-01-00-00。
要解决此问题,请将 projection.dt.range 属性设置为 2022-01-01-01-00,NOW。
相关信息
相关内容
AWS 官方已更新 2 年前
