Athena でのデータのパーティション化 - Amazon Athena

Athena でのデータのパーティション化

データをパーティション分割することで、各クエリによってスキャンされるデータの量を制限できるようになるため、パフォーマンスが向上し、コストが削減されます。すべてのキーでデーNote that this behaviorタをパーティション化できます。一般的な方法では、時間に基づいてデータをパーティション分割します。これにより、通常、複数レベルのパーティション構成となります。たとえば、1 時間ごとに配信されるデータを年、月、日、時間でパーティション分割できます。別の例として、データが配信されるソースが多数に分かれているものの、それらのロードは 1 日 1 回だけ行われる場合には、データソースと日付によるパーティション分割を行います。

Athena では Apache Hive スタイルのパーティションを使用できます。このパーティションのデータパスには、等号で連結されたキーと値のペア (例えば country=us/... または year=2021/month=01/day=26/...) が含まれています。つまり、それぞれのパスにより、パーティションのキーと値、両方の名前が表されます。新しい Hive パーティションをパーティション分割されたテーブルにロードするには、(Hive スタイルのパーティションのみで機能する) MSCK REPAIR TABLE コマンドを使用します。

Athena では、Hive 以外のスタイルのパーティション化スキームを使用することも可能です。例えば、CloudTrail ログや Kinesis Data Firehose の配信ストリームでは、日付部分のコンポーネントが data/2021/01/26/us/6fc7845e.json のように分離されたパスを使用します。これらの Hive と互換性のないデータの場合、パーティションは ALTER TABLE ADD PARTITION により手動で追加します。

考慮事項と制約事項

パーティション分割を使用する場合は、次の点に注意してください。

  • パーティション分割されたテーブルをクエリし、WHERE 句でパーティションを指定する場合、Athena はそのパーティションからのデータしかスキャンしません。詳細については、テーブルの場所とパーティションを参照してください。

  • 多数のオブジェクトがあり、データがパーティション分割されていない Amazon S3 バケットに対してクエリを発行する場合、このようなクエリは Amazon S3 の GET リクエストレート制限に影響を及ぼし、Amazon S3 例外を引き起こす可能性があります。エラーを防ぐには、データをパーティション分割します。また、Amazon S3 のリクエストレートをチューニングすることも検討してください。詳細については、「設計パターンのベストプラクティス: Simple Storage Service (Amazon S3) のパフォーマンスの最適化」を参照してください。

  • Athena で使用されるパーティションの場所は、s3 プロトコル (s3://DOC-EXAMPLE-BUCKET/folder/ など) を使用する必要があります。Athena では、他のプロトコル (s3a://DOC-EXAMPLE-BUCKET/folder/ など) を使用する場所は、そこにあるテーブルに対して MSCK REPAIR TABLE クエリを実行する場合にクエリが失敗する原因になります。

  • Simple Storage Service (Amazon S3) パスがキャメルケースではなく小文字になっていることを確認します (例えば、userId ではなく userid)。S3 パスがキャメルケースの場合、MSCK REPAIR TABLE は AWS Glue Data Catalog にパーティションを追加しません。詳細については、「MSCK REPAIR TABLE」を参照してください。

  • MSCK REPAIR TABLE がフォルダとそのサブフォルダの両方をスキャンして一致するパーティションスキームを検索するため、別個のテーブルのデータは別個のフォルダ階層に保存するようにしてください。例えば、テーブル A のデータが s3://table-a-data にあり、テーブル B のデータが s3://table-a-data/table-b-data にあるとします。両方のテーブルが文字列でパーティション分割されている場合、MSCK REPAIR TABLE はテーブル B のパーティションをテーブル A に追加します。これを避けるには、その代わりに s3://table-a-data および s3://table-b-data といった個別のフォルダ構造を使用します。この動作は、Amazon EMR および Apache Hive と同じであることに注意してください。

  • Athena で AWS Glue Data Catalog を使用している場合は、パーティションに関するサービスクォータについて「AWS Glue エンドポイントとクォータ」を参照してください。

    • Athena では、1,000 万のパーティションを持つ AWS Glue テーブルへのクエリがサポートされていますが、1 回のスキャンで読み取れるのは、100 万のパーティションまでです。

  • AWS Glue Data Catalog を使用しない場合、デフォルトで、テーブルあたりのパーティション数は最大 20,000 です。クォータは、引き上げをリクエストすることができます。

パーティション分割されたデータを使用するテーブルの作成とロード

パーティションを使用するテーブルを作成するには、CREATE TABLE ステートメントの中で PARTITIONED BY 句を使用します。次の例のように、PARTITIONED BY はデータのパーティション分割に使用するキーを定義します。LOCATION 句では、パーティション分割されたデータのルートロケーションを指定します。

CREATE EXTERNAL TABLE users ( first string, last string, username string ) PARTITIONED BY (id string) STORED AS parquet LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/'

テーブルを作成した後、クエリ用にパーティションにデータをロードします。Hive と互換性のあるデータの場合、MSCK REPAIR TABLE を実行します。Hive と互換性のないデータの場合、ALTER TABLE ADD PARTITION を使用してパーティションを手動で追加します。

クエリ用の Hive スタイルおよび非 Hive スタイルデータの準備

以下のセクションでは、Hive スタイルおよび非 Hive スタイルのデータを、Athena でのクエリ向けに準備する方法について説明します。

シナリオ 1: Amazon S3 に Hive 形式で保存されているデータの場合

このシナリオでは、パーティションは Amazon S3 内で別々のフォルダに保存されています。例として、aws s3 ls コマンドが出力した、サンプル広告のインプレッションに関するリスティングの一部を以下に示します。指定されたプレフィックスの下に、S3 オブジェクトがリストされています。

aws s3 ls s3://elasticmapreduce/samples/hive-ads/tables/impressions/ PRE dt=2009-04-12-13-00/ PRE dt=2009-04-12-13-05/ PRE dt=2009-04-12-13-10/ PRE dt=2009-04-12-13-15/ PRE dt=2009-04-12-13-20/ PRE dt=2009-04-12-14-00/ PRE dt=2009-04-12-14-05/ PRE dt=2009-04-12-14-10/ PRE dt=2009-04-12-14-15/ PRE dt=2009-04-12-14-20/ PRE dt=2009-04-12-15-00/ PRE dt=2009-04-12-15-05/

この例では、ログを保存する列名 (dt) が日付、時、分の増分と等しくなるように設定されています。親フォルダの場所、スキーマ、およびパーティション分割されたた列の名前を指定して DDL を提供すると、Athena はこれらのサブフォルダのデータをクエリできます。

テーブルを作成する

このデータからテーブルを作成するには、以下の Athena DDL ステートメントにあるように、「dt」を使用してパーティションを作成します。

CREATE EXTERNAL TABLE impressions ( requestBeginTime string, adId string, impressionId string, referrer string, userAgent string, userCookie string, ip string, number string, processId string, browserCookie string, requestEndTime string, timers struct<modelLookup:string, requestTime:string>, threadId string, hostname string, sessionId string) PARTITIONED BY (dt string) ROW FORMAT serde 'org.apache.hive.hcatalog.data.JsonSerDe' LOCATION 's3://elasticmapreduce/samples/hive-ads/tables/impressions/' ;

このテーブルは、Hive のネイティブ JSON シリアライザー/デシリアライザーを使用して Amazon S3 に保存された JSON データを読み取ります。サポートされる形式の詳細については、「サポートされる SerDes とデータ形式」を参照してください。

MSCK REPAIR TABLE を実行する

CREATE TABLE クエリの実行後、以下の例のように Athena クエリエディタで MSCK REPAIR TABLE コマンドを実行し、パーティションをロードします。

MSCK REPAIR TABLE impressions

このコマンドを実行すると、データにクエリするための準備が整います。

データのクエリ

パーティション列を使用して、インプレッションテーブルのデータをクエリします。例を示します。

SELECT dt,impressionid FROM impressions WHERE dt<'2009-04-12-14-00' and dt>='2009-04-12-13-00' ORDER BY dt DESC LIMIT 100

このクエリにより、次のような結果が表示されます。

2009-04-12-13-20 ap3HcVKAWfXtgIPu6WpuUfAfL0DQEc 2009-04-12-13-20 17uchtodoS9kdeQP1x0XThKl5IuRsV 2009-04-12-13-20 JOUf1SCtRwviGw8sVcghqE5h0nkgtp 2009-04-12-13-20 NQ2XP0J0dvVbCXJ0pb4XvqJ5A4QxxH 2009-04-12-13-20 fFAItiBMsgqro9kRdIwbeX60SROaxr 2009-04-12-13-20 V4og4R9W6G3QjHHwF7gI1cSqig5D1G 2009-04-12-13-20 hPEPtBwk45msmwWTxPVVo1kVu4v11b 2009-04-12-13-20 v0SkfxegheD90gp31UCr6FplnKpx6i 2009-04-12-13-20 1iD9odVgOIi4QWkwHMcOhmwTkWDKfj 2009-04-12-13-20 b31tJiIA25CK8eDHQrHnbcknfSndUk

シナリオ 2: データが Hive 形式でパーティション化されない

次の例では aws s3 ls コマンドにより、Amazon S3 に保存されている ELB ログを表示します。このデータレイアウトでは key=value ペアを使用しておらず、つまり、Hive 形式ではないという点に注意してください。(aws s3 ls コマンドの --recursive オプションは、指定したディレクトリまたはプレフィックスに含まれる、すべてのファイルまたはオブジェクトを一覧表示するように指定します。)

aws s3 ls s3://athena-examples-myregion/elb/plaintext/ --recursive 2016-11-23 17:54:46 11789573 elb/plaintext/2015/01/01/part-r-00000-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:46 8776899 elb/plaintext/2015/01/01/part-r-00001-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:46 9309800 elb/plaintext/2015/01/01/part-r-00002-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:47 9412570 elb/plaintext/2015/01/01/part-r-00003-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:47 10725938 elb/plaintext/2015/01/01/part-r-00004-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:46 9439710 elb/plaintext/2015/01/01/part-r-00005-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:47 0 elb/plaintext/2015/01/01_$folder$ 2016-11-23 17:54:47 9012723 elb/plaintext/2015/01/02/part-r-00006-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:47 7571816 elb/plaintext/2015/01/02/part-r-00007-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:47 9673393 elb/plaintext/2015/01/02/part-r-00008-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:48 11979218 elb/plaintext/2015/01/02/part-r-00009-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:48 9546833 elb/plaintext/2015/01/02/part-r-00010-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:48 10960865 elb/plaintext/2015/01/02/part-r-00011-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:48 0 elb/plaintext/2015/01/02_$folder$ 2016-11-23 17:54:48 11360522 elb/plaintext/2015/01/03/part-r-00012-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:48 11211291 elb/plaintext/2015/01/03/part-r-00013-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:48 8633768 elb/plaintext/2015/01/03/part-r-00014-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:49 11891626 elb/plaintext/2015/01/03/part-r-00015-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:49 9173813 elb/plaintext/2015/01/03/part-r-00016-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:49 11899582 elb/plaintext/2015/01/03/part-r-00017-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:49 0 elb/plaintext/2015/01/03_$folder$ 2016-11-23 17:54:50 8612843 elb/plaintext/2015/01/04/part-r-00018-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:50 10731284 elb/plaintext/2015/01/04/part-r-00019-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:50 9984735 elb/plaintext/2015/01/04/part-r-00020-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:50 9290089 elb/plaintext/2015/01/04/part-r-00021-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:50 7896339 elb/plaintext/2015/01/04/part-r-00022-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 8321364 elb/plaintext/2015/01/04/part-r-00023-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 0 elb/plaintext/2015/01/04_$folder$ 2016-11-23 17:54:51 7641062 elb/plaintext/2015/01/05/part-r-00024-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 10253377 elb/plaintext/2015/01/05/part-r-00025-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 8502765 elb/plaintext/2015/01/05/part-r-00026-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 11518464 elb/plaintext/2015/01/05/part-r-00027-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 7945189 elb/plaintext/2015/01/05/part-r-00028-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 7864475 elb/plaintext/2015/01/05/part-r-00029-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 0 elb/plaintext/2015/01/05_$folder$ 2016-11-23 17:54:51 11342140 elb/plaintext/2015/01/06/part-r-00030-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:51 8063755 elb/plaintext/2015/01/06/part-r-00031-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 9387508 elb/plaintext/2015/01/06/part-r-00032-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 9732343 elb/plaintext/2015/01/06/part-r-00033-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 11510326 elb/plaintext/2015/01/06/part-r-00034-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 9148117 elb/plaintext/2015/01/06/part-r-00035-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 0 elb/plaintext/2015/01/06_$folder$ 2016-11-23 17:54:52 8402024 elb/plaintext/2015/01/07/part-r-00036-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 8282860 elb/plaintext/2015/01/07/part-r-00037-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:52 11575283 elb/plaintext/2015/01/07/part-r-00038-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:53 8149059 elb/plaintext/2015/01/07/part-r-00039-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:53 10037269 elb/plaintext/2015/01/07/part-r-00040-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:53 10019678 elb/plaintext/2015/01/07/part-r-00041-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 2016-11-23 17:54:53 0 elb/plaintext/2015/01/07_$folder$ 2016-11-23 17:54:53 0 elb/plaintext/2015/01_$folder$ 2016-11-23 17:54:53 0 elb/plaintext/2015_$folder$

ALTER TABLE ADD PARTITION を実行する

ここでのデータは Hive 形式ではないため、パーティションの作成後に、テーブルにパーティションを追加するために MSCK REPAIR TABLE コマンドを使用することはできません。代わりに ALTER TABLE ADD PARTITION コマンドを使用することで、各パーティションを手動で追加できます。例えば、s3://athena-examples-myregion/elb/plaintext/2015/01/01/ のデータをロードするには、次のクエリを実行します。Amazon S3 フォルダごとに個別のパーティション列は必要ないこと、およびパーティションキーの値が Amazon S3 キーと同じではない場合があることに注意してください。

ALTER TABLE elb_logs_raw_native_part ADD PARTITION (dt='2015-01-01') location 's3://athena-examples-us-west-1/elb/plaintext/2015/01/01/'

パーティションが既に存在する場合は、Partition already exists というエラーが表示されます。このエラーを回避するには、IF NOT EXISTS 句を使用することができます。詳細については、「ALTER TABLE ADD PARTITION」を参照してください。パーティションを削除する場合は、ALTER TABLE DROP PARTITION を使用します。

パーティション射影

パーティション投影を使用すると、パーティション管理の必要性を回避できます。パーティション投影は、高度にパーティション化されていて、その構造が既知のテーブルで使用できるオプションです。パーティション射影では、パーティションの値と場所はメタデータリポジトリから読み取られるのではなく、テーブルのプロパティ設定を基に算出されます。メモリ内での計算処理は、リモートルックアップよりも高速であるため、パーティション投影を使用することでクエリの実行時間が大幅に短縮されます。

詳細については、「Amazon Athena でのパーティション射影」を参照してください。

その他のリソース