

# パーティション化とは
<a name="ctas-partitioning-and-bucketing-what-is-partitioning"></a>

パーティション化とは、データの特定のプロパティに基づいて Amazon S3 上にあるディレクトリ (または「プレフィックス」) にデータを整理することを意味します。このようなプロパティはパーティションキーと呼ばれます。一般的なパーティションキーは、日付またはその他の時間単位 (年や月など) です。ただし、データセットは複数のキーでパーティション化できます。たとえば、製品の売上に関するデータは、日付、製品カテゴリ、市場ごとにパーティション化できます。

## パーティション化する方法の決定
<a name="ctas-partitioning-and-bucketing-deciding-how-to-partition"></a>

パーティションキーに適しているのは、クエリで常にまたは頻繁に使用され、カーディナリティが低いプロパティです。パーティションの数が多すぎる/少なすぎることについては、それぞれの欠点があります。パーティションが多すぎると、ファイル数が増えるとオーバーヘッドが発生します。また、パーティション自体をフィルタリングすることによるオーバーヘッドもあります。パーティションが少なすぎると、クエリがより多くのデータをスキャンする必要性が多発します。

## パーティショニングされたテーブルを作成する
<a name="ctas-partitioning-and-bucketing-creating-a-partitioned-table"></a>

データセットをパーティション化すると、Athena でパーティションテーブルを作成できます。パーティションテーブルは、パーティションキーを含むテーブルです。`CREATE TABLE` を使用すると、テーブルにパーティションを追加します。`CREATE TABLE AS` を使用すると、Amazon S3 上で作成されたパーティションがテーブルに自動で追加されます。

`CREATE TABLE` ステートメントでは、`PARTITIONED BY (column_name data_type)` 句にパーティションキーを指定します。`CREATE TABLE AS` ステートメントでは、`WITH (partitioned_by = ARRAY['partition_key'])` 句に、または Iceberg テーブルの `WITH (partitioning = ARRAY['partition_key'])` にパーティションキーを指定します。パフォーマンス上の理由から、パーティションキーは常に `STRING` タイプにする必要があります。詳細については、「[パーティションキーのデータ型として文字列を使用](data-types-timestamps.md#data-types-timestamps-partition-key-types)」を参照してください。

その他の `CREATE TABLE` および `CREATE TABLE AS` 構文の詳細については、「[CREATE TABLE](create-table.md)」と「[CTAS テーブルのプロパティ](create-table-as.md#ctas-table-properties)」を参照してください。

## パーティショニングされたテーブルをクエリする
<a name="ctas-partitioning-and-bucketing-querying-partitioned-tables"></a>

パーティションテーブルをクエリすると、Athena はクエリ内の述語を使用してパーティションのリストをフィルタリングします。次に、一致するパーティションの場所を使用して、見つかったファイルを処理します。単純に、クエリ述語と一致しないパーティションのデータを読み取らないようにすることで、Athena がスキャンするデータ量を効率的に減らせます。

### 例
<a name="ctas-partitioning-and-bucketing-partitioned-table-example-queries"></a>

テーブルを `sales_date` と `product_category` でパーティション化していて、特定のカテゴリにおける 1 週間の総収益を知りたいとします。次の例のように、Athena がスキャンするデータ量が最小限になるように、`sales_date` 列と `product_category` 列に述語を含めます。

```
SELECT SUM(amount) AS total_revenue 
FROM sales 
WHERE sales_date BETWEEN '2023-02-27' AND '2023-03-05' 
AND product_category = 'Toys'
```

日付別にパーティション化されているが詳細なタイムスタンプも含むデータセットがあるとします。

Iceberg テーブルではパーティションキーを宣言して列に関係を構築できますが、Hive テーブルではクエリエンジンは列とパーティションキーの関係に関するデータを持っていません。。このため、クエリが必要以上に多くのデータをスキャンしないように、クエリにある列とパーティションキーの両方に述語を含める必要があります。

たとえば、前の例における `sales` テーブルにも `TIMESTAMP` データ型の `sold_at` 列があるとします。特定の時間範囲の収益のみを求める場合は、クエリを次のように記述します:

```
SELECT SUM(amount) AS total_revenue 
FROM sales 
WHERE sales_date = '2023-02-28' 
AND sold_at BETWEEN TIMESTAMP '2023-02-28 10:00:00' AND TIMESTAMP '2023-02-28 12:00:00' 
AND product_category = 'Toys'
```

Hive テーブルと Iceberg テーブルのクエリの違いに関する詳細については、「[同じく時間分割されているタイムスタンプフィールドのクエリを作成する方法](data-types-timestamps.md#data-types-timestamps-how-to-write-queries-for-timestamp-fields-that-are-also-time-partitioned)」を参照してください。