Amazon Athena テーブルにクエリを実行するとレコードがゼロになるのはなぜですか?

所要時間2分
0

Amazon Athena で CREATE TABLE ステートメントを実行しまし、必要な列とそのデータ型を指定しました。SELECT* FROM table-name というクエリを実行すると、出力は「ゼロレコードが返されました。」

解決策

クエリがゼロレコードを返すのには、いくつかの一般的な理由があります。ユースケースに基づいて、一般的な理由とトラブルシューティング手順に関連するセクションを参照してください。

AWS Glue パーティション

クローラー設定で選択したファイル

クローラーを使用する場合は、クローラーがファイルではなく Amazon Simple Storage Service (Amazon S3) バケットを指していることを確認してください。

LOCATION パスが正しくありません

入力データの Amazon S3 LOCATION パスを確認します。入力された LOCATION パスが正しくない場合、Athena はゼロレコードを返します。

LOCATION パスに二重スラッシュ

Athena は、二重スラッシュ (//) を含むテーブル LOCATION パスをサポートしていません。たとえば、次の LOCATION パスは空の結果を返します。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 プレフィックスに保存されている複数のテーブルのデータは、同じ S3 プレフィックスに格納されているデータ用に AWS Glue クローラーによって別々のテーブルが作成されます。ただし、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 データカタログまたは内部の Athena データカタログにまだロードされていない可能性があります。MSCK REPAIR TABLE または ALTER TABLE ADD PARTITION を使用して、パーティション情報をカタログにロードします。

パーティションが Athena がサポートする形式で保存されている場合は、MSCK REPAIR TABLE を実行してパーティションのメタデータをカタログに読み込みます。たとえば、Year でパーティション化されたテーブルがある場合、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;

ハイブ隠しファイル

ファイル名がアンダースコア (\ _) やピリオド (.) で始まっていないことを確認してください。

Athena はこれらのファイルをプレースホルダーと見なし、クエリを処理するときは無視します。詳細については、「Athena は隠しファイルを読み取れない」を参照してください。S3 パス内のすべてのファイルの名前がアンダースコアまたはピリオドで始まる場合、レコードはゼロになります。

**注:**S3 パスに、名前が異なる文字で始まるファイルのほかにプレースホルダーが含まれている場合、Athena はプレースホルダーのみを無視し、他のファイルにクエリを実行します。そのため、1 つ以上のレコードを取得できます。

例:

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

パーティションプロジェクション

パーティションプロジェクションの範囲外の値

パーティションプロジェクションに定義された範囲を超える値のクエリでは、エラーは返されません。代わりに、クエリはゼロ行を返します。

たとえば、データが 2020 年に開始され、projection.timestamp.range'='2020/01/01,NOW と定義されているとします。

このサンプルクエリを実行すると、クエリは正常に完了しますが、0 行が返されます。

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

ストレージテンプレートがデフォルトのパーティションスキームに従っていない

Amazon S3 ファイルの場所がロケーションパターン「.../column=value...」に従わない場合、カスタム Amazon S3 パーティションスキームを指定する必要があります。カスタムスキームを定義しない場合、クエリはゼロレコードを返します。

カスタム S3 パーティションスキームを定義するには、「カスタム S3 ストレージロケーションの指定」を参照してください。

カスタムストレージテンプレートが正しくありません

カスタムテンプレートを使用する場合は、そのテンプレートで Athena がパーティションの場所を構築できることを確認してください。また、各プレースホルダーと Amazon S3 パスの最後には 1 つのフォワードスラッシュが付いていることを確認してください。

たとえば、DDL ステートメント PARTITIOND 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 という場所に、毎日午前 0 時から 1 時間後に送信される時間関連データがあるとします。

この例では、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'

サンプルテーブルで実行されるクエリは、ゼロレコードを返します。これは、予測されるプロパティのファイルロケーションが深夜0時に対応しているためです 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ヶ月前