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

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

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

時間の経過とともに、数十万のパーティションがテーブルに追加されます。GetPartitions API は、テーブル内のパーティションを取得するために使用されます。この API は、リクエストで指定された式と一致するパーティションを返します。

sales_data テーブルを例として、国 、カテゴリ creationDate のキーでパーティション分割します。 2020-08-15 より後に 2020 年に Books カテゴリで販売されたすべての商品の売上データを取得する場合は、「Category = 'Books' and creationDate > '2020-08-15'」という式でデータカタログにGetPartitionsリクエストを行う必要があります。

テーブルにパーティションインデックスが存在しない場合、AWS Glue では、テーブルのすべてのパーティションがロードされ、GetPartitions リクエストでユーザーが指定したクエリ式を使用してロードされたパーティションがフィルタリングされます。インデックスのないテーブルでパーティション数が増えると、クエリの実行に時間がかかります。インデックスを使用すると、GetPartitions クエリでは、テーブル内のすべてのパーティションをロードするのではなく、パーティションのサブセットを取得しようとします。

パーティションインデックスについて

パーティションインデックスを作成する際、指定したテーブルに既に存在するパーティションキーのリストを指定します。パーティションインデックスは、テーブルで定義されているパーティションキーのサブリストです。パーティションインデックスは、テーブルで定義されたパーティションキーを任意の順序にして作成できます。上記の sales_data テーブルでは、可能なインデックスは、 (国、カテゴリ、creationDate)、 (国、カテゴリ、年)、 (国、カテゴリ)、 (カテゴリ、国、年、月) などです。

Data Catalog は、インデックスの作成時に指定された順序でパーティション値を連結します。インデックスは、テーブルに追加されたパーティションと整合して構築されます。インデックスは、文字列 (文字列、char、varchar)、数値 (int、bigint、long、tinyint、smallint)、日付 (yyyy-MM-dd) 列タイプに対して作成できます。

サポートされているデータ型

  • 日付 – などの ISO 形式の日付YYYY-MM-DD。例えば、日付 です2020-08-15。形式は、ハイフン (‐) を使用して年、月、日を区切ります。から 0000-01-01までのインデックス作成の日付の許容範囲9999-12-31

  • 文字列 – 一重引用符または二重引用符で囲まれた文字列リテラル。

  • Char – char(10) など、1~255 の指定された長さの固定長文字データ。

  • Varchar – 可変長の文字データ。varchar(10) など、1~65535 の指定された長さです。

  • 数値 — int、bigint、long、tinyint、smallint

数値、文字列、日付データ型のインデックスは、=、>、>=、<、<=、および 演算子間のサポートしています。インデックス作成ソリューションは現在、AND 論理演算子のみをサポートしています。「LIKE」、「IN」、「OR」、および「NOT」の演算子のある部分式は、インデックスを使用してフィルタリングする場合、この式では無視されます。無視された部分式のフィルタリングは、インデックスフィルタリングを適用した後にフェッチされたパーティションに対して行われます。

テーブルに追加されたパーティションごとに、対応するインデックス項目が作成されます。「n」個のパーティションを持つテーブルの場合、1 つのパーティションインデックスは「n」個のパーティションインデックス項目になります。同じテーブルの「m」個のパーティションインデックスは、「m*n」個のパーティションインデックス項目になります。各パーティションインデックス項目は、現在のデータカタログストレージの AWS Glue 料金ポリシーに従って課金されます。ストレージオブジェクトの料金の詳細については、「AWS Glue の料金」を参照してください。

パーティションインデックスを持つテーブルの作成

テーブルの作成中にパーティションインデックスを作成できます。CreateTable リクエストは、PartitionIndex オブジェクトのリストを入力として指定します。1 つのテーブルには、最大 3 つのパーティションインデックスを作成できます。各パーティションインデックスには、テーブルに対して定義された名前と partitionKeys のリストが必要です。テーブル上に作成されたインデックスは、GetPartitionIndexes API を使用してフェッチできます。

パーティションインデックスの既存テーブルへの追加

既存のテーブルにパーティションインデックスを追加するには、CreatePartitionIndex オペレーションを使用します。CreatePartitionIndex オペレーションごとに、1 つの PartitionIndex を作成できます。インデックスを追加しても、テーブルの可用性には影響しません。これは、インデックスの作成中もテーブルが使用可能になるためです。

追加されたパーティションのインデックスステータスが CREATING に設定され、インデックスデータの作成が開始されます。インデックスの作成プロセスが正常に終了すると、indexStatus は ACTIVE に更新され、プロセスが正常に終了しなかった場合、インデックスステータスは FAILED に更新されます。インデックスが作成できない理由は、複数あり得ます。GetPartitionIndexes オペレーションを使用して、障害の詳細を取得できます。考えられる障害は次のとおりです。

  • ENCRYPTED_PARTITION_ERROR – 暗号化されたパーティションを持つテーブルでのインデックスの作成はサポートされていません。

  • INVALID_PARTITION_TYPE_DATA_ERROR – partitionKey の値が対応する partitionKey データ型に対して有効な値でない場合に発生します。例えば、「int」データ型の partitionKey の値が「foo」の場合などです。

  • MISSING_PARTITION_VALUE_ERROR – indexedKeypartitionValue がない場合に発生します。これは、テーブルのパーティション化に整合性がない場合に発生します。

  • UNSUPPORTED_PARTITION_CHARACTER_ERROR – インデックス付きパーティションキーの値に「\u0000」、「\u0001」、または「\u0002」という文字が含まれている場合に発生します。

  • INTERNAL_ERROR – インデックスの作成中に内部エラーが発生しました。

テーブル上のパーティションインデックスの説明

テーブル上に作成されたパーティションインデックスを取得するには、GetPartitionIndexes オペレーションを使用します。レスポンスとして、テーブル上のすべてのインデックスと、各インデックスの現在のステータス (IndexStatus) が返ります。

パーティションインデックスの IndexStatus は、次のいずれかになります。

  • CREATING – インデックスは現在作成されていますが、まだ使用することはできません。

  • ACTIVE – インデックスは、すぐに使用できます。リクエストにインデックスを使用して最適化されたクエリを実行できます。

  • DELETING – インデックスは現在削除されているため、使用できなくなっています。アクティブ状態のインデックスは、DeletePartitionIndex リクエストを使用してステータスを ACTIVE から DELETING に移行することによって削除できます。

  • FAILED – 既存のテーブルでインデックスの作成に失敗しました。失敗したインデックスは、直近の 10 個まで各テーブルに保存されます。

既存のテーブルで作成されたインデックスには、次のような状態遷移があり得ます。

  • CREATING → ACTIVE → DELETING

  • CREATING → FAILED

パーティションインデックスの使用に関する制限事項

パーティションインデックスを作成したら、テーブルとパーティションの機能に対する次の変更点に注意してください。

新しいパーティションの作成 (インデックスの追加後)

テーブルにパーティションインデックスが作成されると、テーブルに追加されたすべての新しいパーティションは、インデックス付きキーのデータ型チェックのために検証されます。インデックス付きキーのパーティション値は、データ型形式について検証されます。データ型のチェックが失敗すると、パーティションの作成操作は失敗します。sales_data テーブルに対して、キー (カテゴリ、年) のインデックスが作成され、カテゴリの型が string、年の型が int の場合、YEAR の値が「foo」であれば、新しいパーティションの作成は失敗します。

インデックスを有効にすると、U+0000、U+00001、U+0002 という文字を含むインデックス付きキー値のパーティションの追加が失敗するようになります。

テーブルの更新

テーブル上にパーティションインデックスを作成すると、既存のパーティションキーのパーティションキー名を変更することはできません。また、インデックスに登録されているキーのタイプまたは順序を変更することはできません。

最適化された GetPartitions 呼び出しにインデックスを使用する

インデックス付きテーブルで GetPartitions を呼び出すとき、式を含めることができます。また、適用可能な場合は、Data Catalogで、可能であればインデックスが使用されます。インデックスの最初のキーは、フィルタリングに使用されるインデックスの式に含めて渡す必要があります。フィルタリングのインデックスの最適化は、ベストエフォートとして適用されます。Data Catalog では、可能な限りインデックスの最適化を使用しようとしますが、インデックスが見つからない場合、またはサポートされていない演算子の場合は、すべてのパーティションをロードする既存の実装に戻します。

上記の sales_data テーブルには、[Country, Category, Year] (国、カテゴリ、年) のインデックスを追加できます。式に「Country」が渡されない場合、登録されたインデックスは、インデックスを使用したパーティションのフィルタリングができません。最大 3 つのインデックスを追加して、さまざまなクエリパターンをサポートできます。

いくつかの式を例に取り、そこでインデックスが機能する様子を示します。

表現 インデックスの使用方法

Country = 'US'

インデックスは、パーティションをフィルタリングするために使用されます。

Country = 'US' and Category = 'Shoes'

インデックスは、パーティションをフィルタリングするために使用されます。

Category = 'Shoes'

式に「country」が指定されていないため、インデックスは使用されません。レスポンスを返すため、すべてのパーティションがロードされます。

Country = 'US' and Category = 'Shoes' and Year > '2018'

インデックスは、パーティションをフィルタリングするために使用されます。

Country = 'US' and Category = 'Shoes' and Year > '2018' and month = 2

インデックスを使用して、「country = "US" and category = "shoes" and year > 2018」に該当するすべてのパーティションがフェッチされます。その後、月に関する式によるフィルタリングが実行されます。

Country = 'US' AND Category = 'Shoes' OR Year > '2018'

OR 演算子が式に存在するため、インデックスは使用されません。

Country = 'US' AND Category = 'Shoes' AND (Year = 2017 OR Year = '2018')

インデックスを使用して、「country = "US" and category = "shoes"」に該当するのすべてのパーティションがフェッチされ、その後、年に関する式によるフィルタリングが実行されます。

Country in ('US', 'UK') AND Category = 'Shoes'

IN 演算子は現在サポートされていないため、インデックスはフィルタリングに使用されません。

Country = 'US' AND Category in ('Shoes', 'Books')

インデックスを使用して、「country = "US"」に該当するのすべてのパーティションが取得され、その後、カテゴリに関する式によるフィルタリングが実行されます。

国 = 'US' AND Category in ('Shoes', 'Books') AND (creationDate > '2023-9-01'

インデックスは、国が「US」で creationDate > 「2023-9-01」のすべてのパーティションを取得するために使用され、カテゴリ式でのフィルタリングが実行されます。

エンジンとの統合

Redshift Spectrum、Amazon EMR、および AWS Glue ETL Spark DataFrames は、インデックスが の ACTIVE 状態になった後に、パーティションを取得するためのインデックスを利用できますAWS Glue。AthenaAWS Glue ETL DynamicFrame では、クエリを向上させるためにインデックスを利用するには追加のステップに従う必要があります。

パーティションフィルタリングを有効にする

Athena でパーティションフィルタリングを有効にするには、テーブルプロパティを次のように更新する必要があります。

  1. AWS Glue コンソールの データカタログ で、テーブル を選択します。

  2. テーブルを選択します。

  3. アクション で、テーブル の編集 を選択します。

  4. テーブルプロパティ で、以下を追加します。

    • キー –partition_filtering.enabled

    • 値 – true

  5. [適用] を選択します。

または、Athena で ALTER TABLE SET PROPERTIES クエリを実行して、このパラメータを設定することもできます。

ALTER TABLE partition_index.table_with_index SET TBLPROPERTIES ('partition_filtering.enabled' = 'true')