ID の動的なパーティション化 - Amazon Athena

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

ID の動的なパーティション化

テーブルは、次の特性を持つ一意の識別子列でパーティション化されている場合があります。

  • 新しい値を頻繁に (場合によっては自動的に) 追加する。

  • 簡単に生成できない。これらは、定義された範囲内の連続した整数ではなく、構成や長さが変化するユーザー名またはデバイス ID の可能性があります。

このようなパーティションスキームでは、次の理由のため enum 射影タイプが実用的ではない可能性があります。

  • 値がテーブルに追加されるたびに、テーブルプロパティの変更が必要になる可能性があります。

  • 1 つのテーブルプロパティに、数百万文字以上含まれる可能性があります。

  • 射影では、すべてのパーティション列が射影用に設定されている必要があります。この要件は、1 列のみの場合回避できません。

これらの制限を回避するには、injection または bucketing を使用します。

Injection

動的 ID データセットのクエリパターンで、高基数パーティション列に常に単一の値が指定される場合、値挿入を使用できます。挿入により、パーティション領域全体を射影する必要がなくなります。

device_id のようにかなり高基数の UUID フィールドで IoT データセットをパーティション化するとします。このフィールドには以下の特徴があります。

  • 非常に大きい値 (場合によっては数十億)。

  • その値はランダムな文字列であるため、他の射影方法を使用して射影することはできません。

  • 一般的に使用されるメタストアに、非常に多数のパーティションを保存することはできません。

ただし、1 つの device_id だけをフィルタ処理する WHERE 句がすべてのクエリに含まれている場合は、CREATE TABLE ステートメントで次の方法を使用できます。

... PARTITIONED BY ( device_id STRING ) LOCATION "s3://bucket/prefix/" TBLPROPERTIES ( "projection.enabled" = "true", "projection.device_id.type" = "injected", "storage.location.template" = "s3://bucket/prefix/${device_id}" )

このようなテーブルの SELECT クエリは、次のようになります。

SELECT col1, col2,..., device_id FROM table WHERE device_id = "b6319dc2-48c1-4cd5-a0a3-a1969f7b48f7" AND ( col1 > 0 or col2 < 10 )

この例では、Athena は特定のクエリに対して 1 つのパーティションのみを射影します。これにより、1 つのパーティションを見つけてそこから読み取るためだけに、数百万から数十億の仮想パーティションを保存して処理する必要がなくなります。

Bucketing

バケット化手法では、パーティション化の識別子セット全体ではなく、バケット値の固定セットを使用します。識別子をバケットにマッピングできる場合、クエリでこのマッピングを使用できます。識別子自体をパーティション化するときと同じようにメリットがあります。

バケット化には、射影よりも次のような利点があります。

  • WHERE 句のフィールドには、一度に複数の値を指定できます。

  • 従来のメタストアでは、引き続きパーティションを使用できます。

前の例のシナリオを使用し、整数により識別されたバケットが 100 万個あるとすると、CREATE TABLE ステートメントは次のようになります。

... PARTITIONED BY ( BUCKET_ID BIGINT ) LOCATION "s3://bucket/prefix/" TBLPROPERTIES ( "projection.enabled" = "true", "projection.bucket_id.type" = "integer", "projection.bucket_id.range" = "1,1000000" )

対応する SELECT クエリは、次の例のように WHERE 句のマッピング関数を使用します。

SELECT col1, col2,..., identifier FROM table WHERE bucket_id = map_identifier_to_bucket("ID-IN-QUESTION") AND identifier = "ID-IN-QUESTION"

を置き換える map_identifier_to_bucket 識別子を整数にマッピングするスカラー式で使用します。たとえば、式は単純なハッシュまたはモジュラスになります。この関数は、指定された次元に射影できるパーティションの数に一定の上限を適用します。Apache Parquet や ORC などの述語プッシュダウンをサポートするファイル形式と組み合わせると、バケット手法は優れたパフォーマンスを発揮します。

前の例のスカラーバケット関数など、独自のユーザー定義関数を記述する方法については、「ユーザー定義関数を使用したクエリ」を参照してください。