Amazon Athena
ユーザーガイド

バケット化とパーティション化の比較

CTAS クエリの結果からデータを Amazon S3 に保存するために、パーティション化またはバケット化を指定することができます。CTAS クエリの詳細については、「CREATE TABLE AS SELECT (CTAS)」を参照してください。

このセクションでは、CTAS クエリにのみ適用されるパーティション化およびバケット化について説明します。CREATE TABLE クエリでのパーティション化に関する一般的なガイドラインについては、「Amazon Athena のパフォーマンスチューニング Tips トップ 10」を参照してください。

以下のヒントを使用して、パーティション化する、バケットを設定する、あるいは両方実行するかどうかを決定します。さらに、これを実行するために CTAS クエリ内の列を選択します。

  • CTAS クエリ結果のパーティション化は、計画するパーティションの数が限られているときにうまく機能します。CTAS クエリを実行すると、Amazon S3 の指定した場所に Athena が結果を書き込みます。パーティションを指定する場合、パーティションが作成され、同じ場所の個別のパーティションフォルダに各パーティションが保存されます。CTAS クエリ結果で設定できるパーティションの最大数は 100 個です。

    Amazon S3 にパーティションがあると、Athena のクエリパフォーマンスを高められます。これは特定のパーティションのみに対象を限定したクエリを実行できるからです。その結果 Athena は対象のパーティションのみをスキャンし、クエリのコストとクエリ時間を節約します。パーティション化構文については、「CREATE TABLE AS」で partition_by を検索します。

    特性が類似した列 (同じ部門のレコードなど)、さらに値の種類が限られている列 (組織内の限られた部門数など) によりデータをパーティション化します。この特性は、データのカーディナリティとして知られています。たとえば、列 department でパーティション化し、この列には限られた数の値しか保持されない場合は、department のパーティション分割がうまく機能し、クエリのレイテンシーが低下します。

  • CTAS クエリ結果のバケット化は、カーディナリティが高く、値が均等に分散されている列によってデータをバケット化するときにうまく機能します。

    たとえば、timestamp データを保存する列では、非常に多くの異なる値が含まれてしまう可能性があり、それらのデータはデータセット全体で均等に分散されます。つまり、timestamp 型データを格納する列には値が含まれ、NULL 値はありません。これはまた、このような列のデータを多くのバケットに格納できます。ここで、Amazon S3 の各バケットに格納されるデータ量はほぼ同じになります。

    バケット名として 1 つまたは複数の列を使用して、CTAS クエリの結果用に任意の数のバケットを指定することができます。

    CTAS クエリの結果を格納するバケットを示す列を選択するには、値の種類が多い (カーディナリティの高い) 列、およびそのデータをほぼ同じ数に分割して多くのバケットに保管できるような列を使用します。値が含まれていないデータがあるような列はバケット化の適切な対象となりません。これは、データが少ないバケットとデータが大量にあるバケットが生まれることになってしまうからです。これに対し、ほとんど常に値が存在すると予測される列 (timestamp 型の値など) はバケット化に適しています。これはデータのカーディナリティが高く、ほぼ同じ量で格納できるからです。

    バケット化構文については、「CREATE TABLE AS」で bucketed_by を検索します。

最終的な結果を得るために、同じ CTAS クエリの結果を格納するパーティション化とバケットを使用できます。データを書き込むこれらの手法は、共存できます。通常、バケット化に使用する列は、パーティション化に使用するものとは異なります。

たとえば、データセットに列 departmentsales_quarter、および ts がある場合 (強力な timestamp 型データの場合)、department および sales_quarter を基準にして CTAS クエリ結果をパーティション化できます。これらの列の値のカーディナリティは比較的低くなります (部門数や販売地域数は限られています)。また、パーティションでは、データセットの一部のレコードが null であったり、これらの列に割り当てられた値がない場合でも問題ありません。重要なのは、同じ特性のデータ (同じ部門のデータなど) が、Athena でクエリを実行できる 1 つのパーティションに存在することです。

同時に、すべてのデータには、ts 列に保存されている timestamp 型の値があるため、ts 列で同じクエリ結果をバケット化するように設定できます。この列のカーディナリティは高くなります。そのデータは Amazon S3 の複数のバケットに保存できます。反対のシナリオを考えてみます。タイムスタンプ型のデータ用バケットを作成せず、特定の日付値または時刻値でクエリを実行する場合、Amazon S3 の 1 つの場所に保存された、極めて大量のデータをスキャンする必要があります。代わりに、日付と時間に関連した結果を保存するためのバケットを設定した場合、値があるバケットのみをスキャンしてクエリを実行でき、大量のデータをスキャンする、実行時間が長いクエリが不要になります。