テーブルを最適化する - Amazon Athena

テーブルを最適化する

スロットリングの問題が発生した場合は、データを構造化することが重要です。Amazon S3 は大量のデータを処理できますが、データの構造が原因でスロットリングが発生することがあります。

以下のセクションでは、スロットリングの問題を回避するために Amazon S3 でデータを構造化するいくつかの方法について提案します。

パーティション分割を使用する

パーティション分割を使用すると、いつでもアクセスする必要があるデータ量を制限することで、スロットリングを減らすことができます。特定の列のデータをパーティション分割することで、複数のオブジェクトにリクエストを均等に分散し、1 つのオブジェクトに対するリクエスト数を減らすことができます。スキャンする必要のあるデータ量を減らすことは、クエリのパフォーマンスの向上とコストの削減につながります。

テーブルを作成するときに、仮想列として機能するパーティションを定義できます。CREATE TABLE ステートメント内にパーティションを含むテーブルを作成するには、PARTITIONED BY (column_name data_type) 句を使用してデータを分割するキーを定義します。

クエリによってスキャンされるパーティションを制限するには、クエリの WHERE 句にそれらを述語として指定できます。したがって、フィルターとして頻繁に使用される列はパーティション分割に適しています。一般的な方法では、時間間隔に基づいてデータをパーティション化します。これにより、通常、複数レベルのパーティション構成となります。

パーティション分割にはコストもかかることに注意してください。テーブル内のパーティション数を増やすと、パーティションメタデータの取得と処理に必要な時間も長くなります。そのため、パーティション分割が過剰になると、より計画的にパーティション分割を行うことで得られるメリットが得られない可能性があります。データが 1 つのパーティション値に大きく偏っていて、ほとんどのクエリがその値を使用している場合は、追加のオーバーヘッドが発生する可能性があります。

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

データのバケット化

データを分割するもう 1 つの方法は、データを 1 つのパーティションにバケット化することです。バケット化するには、グループ化する行を含む 1 つまたは複数の列を指定します。次に、それらの行を複数のバケットに入れます。この方法では、読み取りが必要なバケットのみをクエリできるため、スキャンする必要のあるデータ行の数が減ります。

バケット化に使用する列を選択する際に、カーディナリティが高く (つまり、多数の異なる値があり)、均一に分布していて、データのフィルタリングによく使用する列を選択します。バケット化に適した列の例としては、ID 列などのプライマリキーがあります。

Athena でのバケット化の詳細については、「バケット化とは」を参照してください。

AWS Glue パーティションインデックスの使用

AWS Glue パーティションインデックスを使用すると、1 つ以上のパーティション値に基づくテーブル内のデータを整理できます。AWS Glue パーティションインデックスを使用すると、データ転送回数、データ処理量、およびクエリの処理時間を削減できます。

AWS Glue パーティションインデックスは、パーティションキーとその値など、テーブル内のパーティションに関する情報を含むメタデータファイルです。パーティションインデックスは Amazon S3 バケットに保存され、新しいパーティションがテーブルに追加されると AWS Glue によって自動的に更新されます。

AWS Glue パーティションインデックスが存在する場合は。クエリでは、テーブル内のすべてのパーティションをロードするのではなく、パーティションのサブセットを取得しようとします。クエリは、クエリに関連するデータのサブセットでのみ実行されます。

AWS Glue でテーブルを作成する際は、テーブルで定義されたパーティションキーの任意の組み合わせに対して、パーティションインデックスを作成できます。テーブルに 1 つ以上のパーティションインデックスを作成したら、パーティションフィルタリングを有効にするプロパティをテーブルに追加する必要があります。その後、Athena からテーブルにクエリを実行できます。

AWS Glue でのパーティションインデックス作成のステップについては、「AWS Glue デベロッパーガイド」の「AWS Glue でパーティションインデックスを使用する」を参照してください。テーブルプロパティを追加してパーティションフィルタリングを有効にする方法については、「AWS Glue パーティションのインデックス作成とフィルタリングでクエリを最適化する」を参照してください。

データ圧縮とファイル分割の使用

ファイルが最適なサイズである場合や、ファイルを論理グループに分割できる場合は、データ圧縮によりクエリを大幅に高速化できます。一般に、圧縮率が高いほど、データを圧縮および解凍するためにより多くの CPU サイクルが必要になります。Athena の場合は、デフォルトでデータを圧縮する Apache Parquet または Apache ORC のいずれかを使用することをお勧めします。Athena でのデータ圧縮の詳細については、「Athena で圧縮を使用する」を参照してください。

ファイルを分割すると、Athena は 1 つのファイルを読み取るタスクを複数のリーダーに分散できるため、並列処理が向上します。1 つのファイルを分割できない場合、他のリーダーがアイドル状態のときに 1 つのリーダーだけがファイルを読み取ることができます。Apache Parquet と Apache ORC は分割可能なファイルもサポートしています。

最適化された列指向データストアを使用する

データを列指向形式に変換すると、Athena クエリのパフォーマンスが大幅に向上します。列指向ファイルを生成する場合、検討すべき最適化手法の 1 つは、パーティションキーに基づいてデータを順序付けることです。

Apache Parquet と Apache ORC は、オープンソースの列指向データストアとしてよく使用されています。既存の Amazon S3 データソースをこれらの形式のいずれかに変換する方法については、「列形式に変換する」を参照してください。

大きい Parquet ブロックサイズまたは ORC ストライプサイズの使用

Parquet と ORC には、調整して最適化できるデータストレージパラメータがあります。Parquet では、ブロックサイズを最適化できます。ORC では、ストライプサイズを最適化できます。ブロックまたはストライプが大きいほど、それぞれに保存できる行が多くなります。デフォルトでは、Parquet のブロックサイズは 128 MB で、ORC のストライプサイズは 64 MB です。

ORC ストライプが 8 MB (hive.orc.max_buffer_size のデフォルト値) 未満の場合、Athena は ORC ストライプ全体を読み取ります。これは、ストライプが小さい場合に、列の選択性と 1 秒あたりの入出力操作の間で Athena が行うトレードオフです。

列数が非常に多いテーブルがある場合、ブロックまたはストライプのサイズが小さいと、必要以上に多くのデータがスキャンされる可能性があります。このような場合は、ブロックサイズを大きくするほうが効率的です。

複合型で ORC を使用する

Parquet に保存されている複雑なデータ型 (例: arraymapstruct) の列に対してクエリを実行する場合、現行では、Athena は指定された列のみを選択して読み取るのではなく、データの列全体を読み込みます。これは Athena における既知の問題です。回避策として、ORC の使用を検討してください。

圧縮アルゴリズムの選択

設定できるもう 1 つのパラメータは、データブロックの圧縮アルゴリズムです。Athena において、Parquet と ORC でサポートされている圧縮アルゴリズムについては、「Athena 圧縮サポート」を参照してください。

Athena での列指向ストレージ形式の最適化の詳細については、AWS ビッグデータのブログ記事「Amazon Athena のパフォーマンスチューニング Tips トップ 10」の「列指向データストア生成の最適化」セクションを参照してください。

Iceberg テーブル

Apache Iceberg は、Amazon S3 で最適に使用できるように設計された、非常に大規模な分析データセット用のオープンテーブル形式です。Iceberg テーブルを使用すると、Amazon S3 のスロットリングを減らすことができます。

Iceberg テーブルには次のような利点があります。

  • Iceberg テーブルは、1 つまたは複数の列でパーティション化できます。これにより、データアクセスが最適化され、クエリでスキャンする必要のあるデータ量が減ります。

  • Iceberg オブジェクトストレージモードでは Iceberg テーブルが Amazon S3 と連携するように最適化されるため、大量のデータや大量のクエリワークロードを処理できます。

  • オブジェクトストレージモードの Iceberg テーブルは、スケーラブルで耐障害性および耐久性があり、スロットリングを減らすのに役立ちます。

  • ACID トランザクションがサポートされているため、複数のユーザーがアトミックな方法で Amazon S3 オブジェクトを追加および削除できます。

Apache Iceberg の詳細については、「Apache Iceberg」を参照してください。Athena で Apache Iceberg テーブルを使用する方法については、「Iceberg テーブルの使用」を参照してください。