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

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

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

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

Athena では、Hive 以外のスタイルのパーティション化スキームを使用することも可能です。たとえば、CloudTrail ログと 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://amzn-s3-demo-bucket/folder/ など) を使用する必要があります。Athena では、他のプロトコル (s3a://amzn-s3-demo-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 がフォルダとそのサブフォルダの両方をスキャンして一致するパーティションスキームを検索するため、別個のテーブルのデータは別個のフォルダ階層に保存するようにしてください。例えば、テーブル 1 のデータが s3://amzn-s3-demo-bucket1 にあり、テーブル 2 のデータが s3://amzn-s3-demo-bucket1/table-2-data にあるとします。両方のテーブルが文字列でパーティション分割されている場合、MSCK REPAIR TABLE はテーブル 2 のパーティションをテーブル 1 に追加します。これを回避するには、この代わりに s3://amzn-s3-demo-bucket2s3://amzn-s3-demo-bucket1 といった別個のフォルダ構造を使用します。この動作は、Amazon EMR および Apache Hive と同じであることに注意してください。

  • Athena で AWS Glue Data Catalog を使用している場合は、「AWS Glue エンドポイントとクォータ」を参照し、アカウントごとおよびテーブルごとのパーティションに関するサービスクォータをご確認ください。

  • AWS Glue Data Catalog を使用している場合にパーティションのクォータの引き上げをリクエストするには、AWS Glue の Service Quotas コンソール を参照してください。

パーティショニングされたデータを含むテーブルを作成およびロードする

パーティションを使用するテーブルを作成するには、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://amzn-s3-demo-bucket'

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

クエリのために Hive スタイルと非 Hive スタイルのデータを準備する

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

このシナリオでは、パーティションは 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 データを読み込みます。サポートされる形式の詳細については、「データ用に SerDe を選択する」を参照してください。

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

次の例では 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 でパーティション射影を使用する」を参照してください。

追加リソース