

# 什么是分区？
<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` 分区的表，您希望了解一周内特定类别的总收入。您可以在 `sales_date` 和 `product_category` 列中包含谓词，以确保 Athena 仅扫描最低数量的数据，如以下示例所示。

```
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)。