バケット化とは
バケット化は、データセットのレコードをバケットと呼ばれるカテゴリに整理する方法です。
この意味におけるバケットとバケット化は Amazon S3 バケットとは異なるため、混同しないでください。データバケットでは、プロパティと同じ値を含むレコードが同じバケットに入ります。レコードはバケット間で可能な限り均等に分散されるため、各バケットにはほぼ同じ量のデータが含まれます。
実際には、バケットはファイルであり、ハッシュ関数がレコードが入るバケットを決定します。バケット化されたデータセットには、パーティション/バケットごとに 1 つ以上のファイルがあります。ファイルが属するバケットはファイル名でエンコードされます。
バケット化のメリット
バケット化は、データセットが特定のプロパティによってバケット化されており、そのプロパティに特定の値があるレコードを取得する際に役立ちます。データはバケット化されているので、Athena は検索するファイルを決定する値を使用できます。たとえば、データセットが customer_id 別にバケット化されていて、特定の顧客に関するすべてのレコードを検索したいとします。Athena はそれらのレコードを含むバケットを特定し、そのバケット内にあるファイルのみを読み取ります。
高基数 (つまり異なる値が多い) 列が均一に分散していて特定の値を頻繁にクエリする列がある際に、バケット化に適している対象が見つかります。
注記
Athena は、INSERT INTO を使用してバケットテーブルに新しいレコードを追加する機能はサポートしていません。
バケット化された列でのフィルタリングでサポートされるデータ型
特定のデータ型を持つバケット列にフィルターを追加できます。Athena は、次のデータ型を持つバケット化された列に対してフィルタリングをサポートしています:
-
BOOLEAN
-
BYTE
-
DATE
-
DOUBLE
-
FLOAT
-
INT
-
LONG
-
SHORT
-
STRING
-
VARCHAR
Hive と Spark のサポート
Athena エンジンバージョン 2 は Hive バケットアルゴリズムを使用するバケット化されたデータセットをサポートし、Athena エンジンバージョン 3 は Apache Spark バケットアルゴリズムもサポートしています。Hive バケット化はデフォルトです。データセットが Spark アルゴリズムを使用してバケット化されている場合は、TBLPROPERTIES 句を使用して bucketing_format プロパティの値を spark に設定します。
注記
Athena では、CREATE TABLE AS SELECT (CTAS) クエリ内のパーティション数は 100 個に制限されています。同様に、INSERT INTO ステートメントを使用すると、宛先テーブルに最大 100 個のパーティションのみを追加できます。
この制限を超えると、HIVE_TOO_MANY_OPEN_PARTITIONS: Exceeded limit of 100 open writers for partitions/buckets (HIVE_TOO_MANY_OPEN_PARTITIONS: パーティション/バケットのオープンライターの制限である 100 を超えました) エラーメッセージが表示されることがあります。これらの制限を回避するには、CTAS ステートメントと、それぞれ最大 100 個のパーティションを作成または挿入する一連の INSERT INTO ステートメントを使用できます。詳細については、「CTAS および INSERT INTO を使用して 100 パーティションの制限を回避する」を参照してください。
既存のバケット化されたデータセット用のテーブルを作成するには、CLUSTERED BY
( 句の後に column)INTO 句を続けて使用します。N BUCKETSINTO 句は、データをバケット化する先のバケットの数を指定します。N BUCKETS
次の CREATE TABLE の例では、sales データセットは customer_id 別に、Spark アルゴリズムを使用して 8 つのバケットにバケット化されています。この CREATE TABLE ステートメントでは、CLUSTERED
BY 句と TBLPROPERTIES 句を使用してプロパティをそれぞれ設定します。
CREATE EXTERNAL TABLE sales (...) ... CLUSTERED BY (`customer_id`) INTO 8 BUCKETS ... TBLPROPERTIES ( 'bucketing_format' = 'spark' )
CREATE TABLE AS のバケット化を指定するには、bucketed_by パラメータと bucket_count パラメータを次の例のように使用します。
CREATE TABLE sales WITH ( ... bucketed_by = ARRAY['customer_id'], bucket_count = 8 ) AS SELECT ...
次のクエリ例では、特定の顧客が 1 週間を通じて購入した製品の名前を検索します。
SELECT DISTINCT product_name FROM sales WHERE sales_date BETWEEN '2023-02-27' AND '2023-03-05' AND customer_id = 'c123'
このテーブルを sales_date 別にパーティション化して customer_id 別にバケット化すると、Athena は顧客レコードが入っているバケットを計算できます。Athena が読み込めるのは 1 パーティションにつき 1 ファイルまでです。