

# 工作负载管理
<a name="workload-management"></a>

您可以使用 Athena 的工作组、容量管理、性能调整、压缩支持、标签和服务限额功能来管理您的工作负载。

**Topics**
+ [使用工作组控制查询访问和成本](workgroups-manage-queries-control-costs.md)
+ [管理查询处理容量](capacity-management.md)
+ [优化 Athena 性能](performance-tuning.md)
+ [在 Athena 中使用压缩](compression-formats.md)
+ [标记 Athena 资源](tags.md)
+ [服务配额](service-limits.md)

# 使用工作组控制查询访问和成本
<a name="workgroups-manage-queries-control-costs"></a>

您可以使用 Athena 工作组来分离工作负载、控制团队访问权限、强制配置以及跟踪查询指标和控制成本。

**分离工作负载**  
您可以使用工作组来分离工作负载。例如，您可以创建两个独立工作组，一个用于报告生成等自动计划的应用程序，另一个供分析师临时使用。

**控制团队访问权限**  
由于工作组可作为 IAM 资源，因此您可以使用基于资源级身份的策略来控制谁可以访问工作组以及谁可以在其中运行查询。要隔离组织中两个不同团队的查询，可以为每个团队创建一个单独的工作组。每个工作组仅为其中的查询显示查询历史和已保存的查询列表，而不会为账户中的所有查询显示这些信息。有关更多信息，请参阅 [使用 IAM 策略控制工作组访问](workgroups-iam-policy.md)。

**执行配置**  
您可以选择对工作组中运行的所有查询强制使用相同的工作组范围设置。这些设置包括 Amazon S3 中的查询结果位置、预期存储桶拥有者、加密，以及对写入查询结果存储桶的对象的控制权。有关更多信息，请参阅 [Override client-side settings (覆盖客户端设置)](workgroups-settings-override.md)。

**跟踪查询指标、查询事件和控制成本**  
要跟踪每个 Athena 工作组的查询指标、查询事件和控制成本，您可以使用以下功能：
+ **发布查询指标**：将您的工作组的查询指标发布到 CloudWatch。在 Athena 控制台中，您可以针对每个工作组查看查询指标。在 CloudWatch 中，您可以创建自定义控制面板，并为这些指标设置阈值和警报。有关更多信息，请参阅[启用 Athena 中的 CloudWatch 查询指标](athena-cloudwatch-metrics-enable.md)和[使用 CloudWatch 监控 Athena 查询指标](query-metrics-viewing.md)。
+ **监控 Athena 使用情况指标**：在 CloudWatch 图表和控制面板上显示当前服务使用情况，以了解您的账户对资源的使用情况。有关更多信息，请参阅 [使用 CloudWatch 监控 Athena 使用情况指标](monitoring-athena-usage-metrics.md)。
+ **监控查询事件**：使用 Amazon EventBridge 接收有关查询状态的实时通知。有关更多信息，请参阅 [使用 EventBridge 监控 Athena 查询事件](athena-events.md)。
+ **创建数据使用控制**：在 Athena 中，您可以针对每个查询和每个工作组配置数据使用控制。Athena 会在查询超过指定阈值时取消查询，或者在超出工作组阈值时激活 Amazon SNS 警报。有关更多信息，请参阅 [配置每个查询和每个工作组的数据使用情况控制](workgroups-setting-control-limits-cloudwatch.md)。
+ **使用成本分配标签**：使用账单和成本管理控制台为工作组添加成本分配标签。与工作组中运行查询相关的费用会在具有相应成本分配标签的“成本和使用情况报告”中显示。有关更多信息，请参阅《AWS Billing User Guide》**中的 [Using user-defined cost allocation tags](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/custom-tags.html)。
+ **使用容量预留**：您可以使用您指定的数据处理单元数量创建容量预留，然后向预留中添加一个或多个工作组。有关更多信息，请参阅 [管理查询处理容量](capacity-management.md)。

请参阅 AWS Big Data Blog 文章 [Separate queries and managing costs using Amazon Athena workgroups](https://aws.amazon.com/blogs/big-data/separating-queries-and-managing-costs-using-amazon-athena-workgroups/)，了解有关使用 Athena 工作组分离工作负载、控制用户访问权限以及管理查询使用情况和成本的更多信息。

**注意**  
现在可以在 Amazon SageMaker 融通式合作开发工作室（预览版）中访问 Amazon Athena，它可以帮助您访问组织的数据，并使用最佳工具对其采取措施。您可以将保存的查询从 Athena 工作组迁移到 SageMaker 融通式合作开发工作室，使用现有 Athena 工作组配置项目，并通过 IAM 角色更新来维护必要的权限。有关更多信息，请参阅[将 Amazon Athena 资源迁移到 Amazon SageMaker 融通式合作开发工作室（预览版）](https://github.com/aws/Unified-Studio-for-Amazon-Sagemaker/tree/main/migration/athena)。

## 注意事项和限制
<a name="workgroups-considerations-limitations"></a>

当您在 Athena 中使用工作组时，请记住以下几点：
+ 每个账户都具有一个主要工作组。默认情况下，如果您尚未创建任何工作组，则账户中的所有查询在主工作组中运行。不能删除主工作组。默认权限允许所有经过身份验证的用户访问该工作组。
+ 有权访问工作组时，可以查看工作组的设置、指标和数据使用控制限制。通过其他权限，您可以编辑设置和数据使用控制限制。
+ 运行查询时，其会在该工作组中运行。您可以通过 API 操作、命令行界面或使用 JDBC 或 ODBC 驱动程序通过客户端应用程序在控制台中运行该工作组上下文中的查询。
+ 在 Athena 控制台查询编辑器中，您最多可以在每个工作组中打开十个查询选项卡。当您在工作组之间切换时，最多可将三个工作组中的查询选项卡保持打开状态。
+ 在您自己的账户中，最多可对每个 AWS 区域 创建 1000 个工作组。
+ 可以禁用工作组。禁用工作组可防止在其中运行查询，直到您重新启用工作组。
+ 如果您尝试删除包含已保存查询的工作组，Athena 会向您发出警告。在删除其他用户有权访问的工作组之前，确保这些用户有权访问可以从中运行查询的另一工作组。

**Topics**
+ [注意事项和限制](#workgroups-considerations-limitations)
+ [创建工作组](creating-workgroups.md)
+ [管理工作组](workgroups-create-update-delete.md)
+ [使用 CloudWatch 和 EventBridge 监控查询](workgroups-control-limits.md)
+ [使用 Athena 工作组 API](workgroups-api-list.md)
+ [对工作组进行故障排除](workgroups-troubleshooting.md)

# 创建工作组
<a name="creating-workgroups"></a>

创建工作组需要具有执行 `CreateWorkgroup` API 操作的权限。请参阅[配置对工作组和标签的访问](workgroups-access.md)和[使用 IAM 策略控制工作组访问](workgroups-iam-policy.md)。如果要添加标签，您还需要添加对 `TagResource` 的权限。请参阅[工作组的标签策略示例](tags-access-control.md#tag-policy-examples-workgroups)。

以下过程介绍了如何使用 Athena 控制台创建工作组。要使用 Athena API 创建工作组，请参阅[创建工作组](https://docs.aws.amazon.com/athena/latest/APIReference/API_CreateWorkGroup.html)。

**在 Athena 控制台中创建工作组**

1.  确定要创建的工作组。需要考虑的几项因素包括：
   + 哪些用户可以运行每个工作组中的查询，以及哪些用户拥有工作组配置。使用 IAM 策略强制执行工作组权限。有关更多信息，请参阅 [使用 IAM 策略控制工作组访问](workgroups-iam-policy.md)。
   + 在 Amazon S3 中用于工作组查询结果的位置。工作组的所有用户必须能够访问此位置。
   + 是否必须对工作组查询结果进行加密。由于加密按工作组进行（而非按查询进行），因此您应该为加密和非加密的查询结果创建单独的工作组。有关更多信息，请参阅 [加密在 Amazon S3 中存储的 Athena 查询结果](encrypting-query-results-stored-in-s3.md)。

1. 如果控制台导航窗格不可见，请选择左侧的扩展菜单。  
![\[选择扩展菜单。\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/nav-pane-expansion.png)

1. 在 Athena 控制台导航窗格中，选择 **Workgroups**（工作组）。

1. 在 **Workgroups**（工作组）页面中，选择 **Create workgroup**（创建工作组）。

1. 在 **Create workgroup**（创建工作组）页面中，如下所示填写各字段：    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/creating-workgroups.html)

1. 选择 **Create workgroup (创建工作组)**。工作组显示在 **Workgroups **（工作组）页面上的列表中。

   在查询编辑器中，Athena 将在控制台右上角的**工作组**选项中显示当前工作组。您可以使用此选项切换工作组。运行查询时，其会在该工作组中运行。

1. 为您的用户、组或角色创建 IAM policy，使他们能够访问工作组。这些策略建立工作组成员资格，以及对`workgroup`资源相关操作的访问权限。有关更多信息，请参阅 [使用 IAM 策略控制工作组访问](workgroups-iam-policy.md)。有关示例 JSON 策略，请参阅[配置对工作组和标签的访问](workgroups-access.md)。

1. （可选）当未针对覆盖客户端设置选项强制设置工作组范围加密时，可在 Amazon S3 中为工作组的所有查询结果配置最低级别的加密。您可以使用此功能确保查询结果永远不会以未加密状态存储在 Amazon S3 存储桶中。有关更多信息，请参阅 [为工作组配置最低加密](workgroups-minimum-encryption.md)。

1. （可选）使用 Amazon CloudWatch 和 Amazon EventBridge 监控工作组的查询并控制成本。有关更多信息，请参阅 [使用 CloudWatch 和 EventBridge 监控查询并控制成本](workgroups-control-limits.md)。

1. （可选）使用账单和成本管理控制台，以成本分配标签标记工作组。有关更多信息，请参阅《AWS Billing User Guide》**中的 [Using user-defined cost allocation tags](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/custom-tags.html)。

1. （可选）要获得工作组中查询的专用处理容量，请将该工作组添加到容量预留中。您可以将一个或多个工作组分配给预留。有关更多信息，请参阅 [管理查询处理容量](capacity-management.md)。

# Override client-side settings (覆盖客户端设置)
<a name="workgroups-settings-override"></a>

创建或编辑工作组时，您可以选择**覆盖客户端设置**选项。此选项非默认选定。根据您是否选择它，Athena 会执行以下操作：
+ 如果**覆盖客户端设置**未被选中，则不会在客户端级别强制实施工作组设置。当未为工作组选择覆盖客户端设置选项时，Athena 会将客户端设置用于工作组中运行的所有查询，包括查询结果位置、预期存储桶所有者、加密和写入查询结果存储桶的对象控制的设置。每个用户都可以在控制台的**设置**菜单中指定自己的设置。如果未设置客户端设置，则会应用工作组范围设置。如果您使用 AWS CLI、API 操作或 JDBC 和 ODBC 驱动程序在不覆盖客户端设置的工作组中运行查询，则您的查询将使用您在查询中指定的设置。
+ 如果**覆盖客户端设置**被选中，则会在工作组级别对工作组中的所有客户端强制实施工作组设置。当为工作组选择覆盖客户端设置选项时，Athena 会将工作组设置用于工作组中运行的所有查询，包括查询结果位置、预期存储桶所有者、加密和写入查询结果存储桶的对象控制的设置。工作组设置会覆盖您在使用控制台、API 操作或 JDBC 或 ODBC 驱动程序时为查询指定的任何客户端设置。在完成工作组设置以覆盖客户端设置后，可以省略在驱动程序或 API 中指定客户端设置的操作。

  如果您覆盖客户端设置，则您或任何工作组用户下一次打开 Athena 控制台时，Athena 会通知您该工作组中的查询使用工作组设置，并提示您确认此更改。
**注意**  
由于覆盖客户端设置可能会破坏基于任意 Amazon S3 存储桶中结果可用性的自定义自动化，因此我们建议您在覆盖之前通知用户。
**重要**  
如果您使用 API 操作、AWS CLI 或 JDBC 和 ODBC 驱动程序在覆盖客户端设置的工作组中运行查询，请确保在查询中省略客户端设置或更新它们以匹配工作组的设置。  
如果您在查询中指定了客户端设置，但在覆盖设置的工作组中运行这些设置，则查询将运行，但将使用工作组设置。有关查看工作组设置的信息，请参阅 [查看工作组详细信息](viewing-details-workgroups.md)。

# 管理工作组
<a name="workgroups-create-update-delete"></a>

在 Athena 控制台（[https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)）中，您可以执行以下任务：




| 语句 | 说明 | 
| --- | --- | 
|  [创建工作组](creating-workgroups.md)  |  创建新的工作组  | 
| [查看工作组详细信息](viewing-details-workgroups.md) | 查看工作组的详细信息，例如其名称、描述、数据使用限制、查询结果位置、预期查询结果存储桶拥有者、加密，以及对写入查询结果存储桶的对象的控制权。如果 Override client-side settings (覆盖客户端设置) 已被选中，您还可以验证该工作组是否已强制实施其设置。 | 
|  [为查询指定工作组](specify-wkgroup-to-athena-in-which-to-run-queries.md)  |  您必须为 Athena 指定要使用的工作组，然后才能运行查询。您必须具有工作组的权限。  | 
|  [切换工作组](switching-workgroups.md)  |  在您有权访问的工作组之间切换。  | 
|  [编辑工作组](editing-workgroups.md)  | 编辑工作组并更改其设置。您不能更改工作组的名称，但您可以创建一个具有相同设置但名称不同的新工作组。 | 
|  [启用或禁用工作组](workgroups-enabled-disabled.md)  |  启用或禁用工作组。当工作组处于禁用状态，其用户无法运行查询或创建新的命名查询。如果您有权访问它，您仍然可以查看指标、数据使用限制控制、工作组设置，查询历史记录和已保存查询。  | 
|  [在工作组之间复制已保存的查询](copy-a-query-between-workgroups.md)  | 在工作组之间复制已保存的查询。例如，如果您在预览工作组中创建了查询，并且希望在非预览工作组中使用该查询，则可能需要执行此操作。 | 
|  [删除工作组](deleting-workgroups.md)  |  删除工作组。如果您删除某个工作组，则查询历史记录、已保存查询、工作组设置和查询数据限制控制都将被删除。工作组范围的数据限制控制会保留在 CloudWatch 中，您可以单独删除它们。 不能删除主工作组。  | 
| [使用 IAM 策略控制工作组访问](workgroups-iam-policy.md) | 使用 IAM 策略控制工作组访问。有关示例工作组策略，请参阅[工作组策略示例](example-policies-workgroup.md)。 | 
| [创建使用 IAM Identity Center 身份验证的 Athena 工作组](workgroups-identity-center.md) | 要在 Athena 中使用 IAM Identity Center 身份，必须创建一个启用了 IAM Identity Center 的工作组。创建工作组后，您可以使用 IAM Identity Center 控制台或 API 将 IAM Identity Center 用户或组分配给工作组。 | 
| [为工作组配置最低加密](workgroups-minimum-encryption.md) | 在 Amazon S3 中对该工作组的所有查询结果强制执行最低级别的加密。使用此功能确保查询结果永远不会以未加密状态存储在 Amazon S3 存储桶中。 | 

# 查看工作组详细信息
<a name="viewing-details-workgroups"></a>

您可以查看每个工作组的详细信息。这些详细信息包括工作组名称、描述、启用还是禁用以及用于在该工作组中运行的查询的设置，其中包括查询结果位置、预期存储桶拥有者、加密，以及对写入查询结果存储桶的对象的控制权。如果工作组具有数据使用限制，也会显示出来。

**查看工作组详细信息**

1. 在 Athena 控制台导航窗格中，选择 **Workgroups**（工作组）。

1. 在 **Workgroups**（工作组）页面上，选择要查看的工作组的链接。显示工作组的 **Overview Details**（概览详细信息）页面。

# 为查询指定工作组
<a name="specify-wkgroup-to-athena-in-which-to-run-queries"></a>

若要指定要使用的工作组，您必须具有该工作组的权限。

**指定要使用的工作组**

1. 确保您的权限允许您在要使用的工作组中运行查询。有关更多信息，请参阅 [使用 IAM 策略控制工作组访问](workgroups-iam-policy.md)。

1.  若要指定工作组，请使用以下选项之一：
   + 如果您正在使用 Athena 控制台，请通过[切换工作组](switching-workgroups.md)设置工作组。
   + 如果您正在使用 Athena API 操作，请在 API 操作中指定工作组名称。例如，您可以在 [StartQueryExecution](https://docs.aws.amazon.com/athena/latest/APIReference/API_StartQueryExecution.html) 中设置工作组名称，如下所示：

     ```
     StartQueryExecutionRequest startQueryExecutionRequest = new StartQueryExecutionRequest()
                   .withQueryString(ExampleConstants.ATHENA_SAMPLE_QUERY)
                   .withQueryExecutionContext(queryExecutionContext)
                   .withWorkGroup(WorkgroupName)
     ```
   + 如果您正在使用 JDBC 或 ODBC 驱动程序，使用 `Workgroup` 配置参数在连接字符串中设置工作组名称。驱动程序将工作组名称传递到 Athena。在连接字符串中指定工作组参数，如以下示例所示：

     ```
     jdbc:awsathena://AwsRegion=<AWSREGION>;UID=<ACCESSKEY>;
     PWD=<SECRETKEY>;S3OutputLocation=s3://amzn-s3-demo-bucket/<athena-output>-<AWSREGION>/;
     Workgroup=<WORKGROUPNAME>;
     ```

# 切换工作组
<a name="switching-workgroups"></a>

如果您具有两个工作组的权限，则可以从一个工作组切换到另一个工作组。

在每个工作组中，您可以打开最多十个查询选项卡。当您在工作组之间切换时，最多可将三个工作组中的查询选项卡保持打开。

**切换工作组**

1. 在 Athena 控制台中，使用右上角的 **Workgroup**（工作组）选项来选择工作组。

1. 如果出现 **Workgroup *workgroup-name* settings**（工作组 workgroup-name 设置）对话框，请选择 **Acknowledge**（确认）。

**Workgroup**（工作组）选项将显示已切换到的工作组名称。现在，您可以运行该工作组中的查询。

# 编辑工作组
<a name="editing-workgroups"></a>

编辑工作组需要具有执行 `UpdateWorkgroup` API 操作的权限。请参阅[配置对工作组和标签的访问](workgroups-access.md)和[使用 IAM 策略控制工作组访问](workgroups-iam-policy.md)。如果要添加或编辑标记，您还需要具有对 `TagResource` 的权限。请参阅[工作组的标签策略示例](tags-access-control.md#tag-policy-examples-workgroups)。

**在控制台中编辑工作组**

1. 在 Athena 控制台导航窗格中，选择 **Workgroups**（工作组）。

1. 在 **Workgroups**（工作组）页面上，选择要编辑的工作组的按钮。

1. 选择 **Actions**（操作）和 **Edit**（编辑）。

1. 根据需要更改字段。有关字段的列表，请参阅[创建工作组](creating-workgroups.md)。您可以更改除工作组名称以外的所有字段。如果您需要更改名称，请创建具有新名称和相同设置的另一工作组。

1. 选择**保存更改**。已更新的工作组显示在 **Workgroups **（工作组）页面上的列表中。

# 启用或禁用工作组
<a name="workgroups-enabled-disabled"></a>

如果您拥有相应的权限，您可以在控制台中、使用 API 操作或者使用 JDBC 和 ODBC 驱动程序启用或禁用工作组。

**启用或禁用工作组**

1. 在 Athena 控制台导航窗格中，选择 **Workgroups**（工作组）。

1. 在 **Workgroups**（工作组）页面上，选择工作组的链接。

1. 在右上角，选择 **Enable workgroup**（启用工作组）或 **Disable workgroup**（禁用工作组）。

1. 在确认提示处，选择 **Enable**（启用）或 **Disable**（禁用）。如果您禁用一个工作组，其用户无法运行其中的查询或创建新的命名查询。如果您启用一个工作组，用户可以使用它来运行查询。

# 在工作组之间复制已保存的查询
<a name="copy-a-query-between-workgroups"></a>

目前，Athena 控制台没有将保存的查询从一个工作组直接复制到另一个工作组的选项，但您可以使用以下过程手动执行相同的任务。

**要在工作组之间复制保存的查询**

1. 在 Athena 控制台中，从您想复制查询的工作组中，选择 **Saved queries**（保存的查询）选项卡。

1. 选择要复制的已保存查询的链接。Athena 会在查询编辑器中打开查询。

1. 在查询编辑器中，选择查询文本，然后按 **Ctrl\$1C** 以复制查询。

1. [切换](switching-workgroups.md)到目标工作组，或[创建工作组](creating-workgroups.md)，然后切换到该工作组。

1. 在查询编辑器中打开一个新选项卡，然后按 **Ctrl\$1V** 将文本粘贴到新选项卡中。

1. 在查询编辑器中，选择 **Save as**（另存为）将查询保存到目标工作组中。

1. 在 **Choose a name**（选择一个名称）对话框中，输入查询名称和可选说明。

1. 选择**保存**。

# 删除工作组
<a name="deleting-workgroups"></a>

如果您具有相应权限，则可以删除工作组。不能删除主工作组。

如果您有权限，则可以随时删除空工作组。您也可以删除包含已保存查询的工作组。在这种情况下，Athena 会警告您保存的查询将被删除，然后再继续删除工作组。

如果您删除正在其中的工作组，控制台会将焦点切换到主工作组。如果您有权访问它，可以运行查询并查看其设置。

如果您删除某个工作组，其设置和查询数据限制控制都将被删除。工作组范围的数据限制控制保留在 CloudWatch 中，您可以在需要时从中删除它们。

**重要**  
在删除工作组之前，确保其用户同时属于其他工作组，从而可以从中继续运行查询。如果用户的 IAM policy *仅*允许他们允许该工作组中的查询，而您删除了它，则他们将不再具有运行查询的权限。有关更多信息，请参阅 [Example policy for running queries in the primary workgroup](example-policies-workgroup.md#example4-run-in-primary-access)。

**在控制台中删除工作组**

1. 在 Athena 控制台导航窗格中，选择 **Workgroups**（工作组）。

1. 在 **Workgroups**（工作组）页面上，选择要删除的工作组的按钮。

1. 依次选择**操作**和**删除**。

1. 在 **Delete workgroup**（删除工作组）确认提示处，输入工作组名称，然后选择 **Delete**（删除）。

要使用 API 操作删除工作组，请使用 `DeleteWorkGroup` 操作。

# 使用 CloudWatch 和 EventBridge 监控查询并控制成本
<a name="workgroups-control-limits"></a>

通过使用工作组，您可以为每个查询或工作组设置数据使用控制限制，在超出这些限制时发出警报，并将查询指标发布到 CloudWatch。

在每个工作组中，您可以执行以下操作：
+ 为每个查询和每个工作组配置**数据使用控制**，并建立在查询超出阈值时将采取的操作。
+ 查看和分析查询指标，并将它们发布到 CloudWatch。如果在控制台中创建工作组，那么将为您选中将指标发布到 CloudWatch 这一设置。如果使用 API 操作，那么必须[启用发布指标](athena-cloudwatch-metrics-enable.md)。发布指标时，它们将显示在 **Workgroups**（工作组）面板的 **Metrics**（指标）选项卡中。默认情况下，将为主工作组禁用指标。

## 视频
<a name="athena-cloudwatch-metrics-video"></a>

以下视频演示了如何在 CloudWatch 中创建自定义控制面板并设置指标告警和触发器。您可以从 Athena 控制台直接使用预先填充的控制面板来使用这些查询指标。

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/x1V_lhkdKCg/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/x1V_lhkdKCg)


**Topics**
+ [视频](#athena-cloudwatch-metrics-video)
+ [启用查询指标](athena-cloudwatch-metrics-enable.md)
+ [使用 CloudWatch 监控查询指标](query-metrics-viewing.md)
+ [使用 CloudWatch 监控使用情况指标](monitoring-athena-usage-metrics.md)
+ [使用 EventBridge 监控查询事件](athena-events.md)
+ [配置数据使用情况控制](workgroups-setting-control-limits-cloudwatch.md)

# 启用 Athena 中的 CloudWatch 查询指标
<a name="athena-cloudwatch-metrics-enable"></a>

在控制台中创建工作组时，默认情况下将选中将查询指标发布到 CloudWatch 这一设置。

**在 Athena 控制台中为工作组启用或禁用查询指标**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 如果控制台导航窗格不可见，请选择左侧的扩展菜单。  
![\[选择扩展菜单。\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/nav-pane-expansion.png)

1. 在导航窗格中，选择 **Workgroups**（工作组）。

1. 选择要修改的工作组链接。

1. 在工作组的详细信息页面上，选择 **Edit**（编辑）。

1. 在**设置**部分中，选择或清除**将查询指标发布到 AWS CloudWatch**。

如果您使用 API 操作、命令行界面或带 JDBC 驱动程序的客户端应用程序来创建工作组，要启用查询指标发布，请在 [WorkGroupConfiguration](https://docs.aws.amazon.com/athena/latest/APIReference/API_WorkGroupConfiguration.html) 中将 `PublishCloudWatchMetricsEnabled` 设置为 `true`。以下示例仅显示指标配置，省略了其他配置：

```
"WorkGroupConfiguration": { 
      "PublishCloudWatchMetricsEnabled": "true"
     ....
     }
```

# 使用 CloudWatch 监控 Athena 查询指标
<a name="query-metrics-viewing"></a>

如果选择 [publish query metrics to CloudWatch](athena-cloudwatch-metrics-enable.md)（将查询指标发布到 CloudWatch）选项，Athena 会将与查询相关的指标发布到 Amazon CloudWatch。您可以创建自定义控制面板，对 CloudWatch 中的指标设置警报和触发器，或从 Athena 控制台直接使用预先填充的控制面板。

为工作组中的查询启用查询指标时，这些指标将显示在 **Workgroups**（工作组）面板中的 **Metrics**（指标）选项卡，用于 Athena 控制台中的每个工作组。

Athena 会将以下指标发布到 CloudWatch 控制台：
+ `DPUAllocated` – 在容量预留中预置的用于运行查询的 DPU（数据处理单元）总数。
+ `DPUConsumed` – 在预留的给定时间内，处于 `RUNNING` 状态的查询主动消耗的 DPU 数量。只有当工作组与容量预留关联并且包括与预留关联的所有工作组时，才会发出指标。
+ `DPUCount` – 查询消耗的最大 DPU 数量，仅在查询完成时发布一次。
+ `EngineExecutionTime` – 运行查询所耗费的毫秒数。
+ `ProcessedBytes` – Athena 为每个 DML 查询扫描的字节数。
+ `QueryPlanningTime` – Athena 计划查询处理流程所耗费的毫秒数。
+ `QueryQueueTime` – 查询在查询队列中等待资源所耗费的毫秒数。
+ `ServicePreProcessingTime` – 在将查询提交给查询引擎之前，Athena 用于预处理查询的毫秒数。
+ `ServiceProcessingTime` – 查询引擎执行完查询后，Athena 处理查询结果所耗费的毫秒数。
+ `TotalExecutionTime` – Athena 运行 DDL 或 DML 查询所耗费的毫秒数。

有关更完整的说明，请参阅本文档后面的 [Athena 的 CloudWatch 指标与维度列表](#athena-cloudwatch-metrics-table)。

这些指标具有以下维度：
+ `CapacityReservation` – 用于执行查询的容量预留的名称（如果适用）。
+ `QueryState`：`SUCCEEDED`、`FAILED` 或 `CANCELED`
+ `QueryType`：`DML`、`DDL` 或 `UTILITY`
+ `WorkGroup` – 工作组的名称

Athena 会将以下指标发布到 `AmazonAthenaForApacheSpark` 命名空间下的 CloudWatch 控制台：
+ `DPUCount` – 会话期间为执行计算而使用的 DPU 数量。

该指标具有以下维度：
+ `SessionId` – 提交计算的会话 ID。
+ `WorkGroup` – 工作组名称。

有关更多信息，请参阅本主题后面的 [Athena 的 CloudWatch 指标与维度列表](#athena-cloudwatch-metrics-table)。有关 Athena 使用情况指标的信息，请参阅 [使用 CloudWatch 监控 Athena 使用情况指标](monitoring-athena-usage-metrics.md)。

您可以在 Athena 控制台或 CloudWatch 控制台中查看查询指标。

## 在 Athena 控制台中查看查询指标
<a name="query-metrics-viewing-athena-console"></a>

**在 Athena 控制台中查看工作组的查询指标**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 如果控制台导航窗格不可见，请选择左侧的扩展菜单。  
![\[选择扩展菜单。\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/nav-pane-expansion.png)

1. 在导航窗格中，选择 **Workgroups**（工作组）。

1. 从列表中选择所需的工作组，然后选择 **Metrics**（指标）选项卡。

   此时将显示指标控制面板。
**注意**  
如果您最近刚为工作组启用了指标和/或没有最近的查询活动，则控制面板上的图形可能为空。根据您在下一步中指定的间隔从 CloudWatch 检索查询活动。

1. 在 **Metrics**（指标）部分中，选择 Athena 应该用于从 CloudWatch 中提取查询指标的指标间隔，或指定自定义间隔。  
![\[在 Athena 控制台中为工作组指定指标检索间隔。\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/wg-custom-interval.png)

1. 要刷新显示的指标，请选择刷新图标。  
![\[选择刷新图标。\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/wg-refresh-metrics.png)

1. 单击刷新图标旁边的箭头，选择指标显示的更新频率。  
![\[为 Athena 控制台中的工作组指标显示选择刷新间隔。\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/wg-choose-refresh-interval.png)

## 在 CloudWatch 控制台中查看查询指标
<a name="query-metrics-viewing-cw-console"></a>

**要使用 Amazon CloudWatch 控制台查看指标**

1. 通过 [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) 打开 CloudWatch 控制台。

1. 在导航窗格中，依次选择 **Metrics**（指标）、**All metrics**（所有指标）。

1. 选择 **AWS/Athena** 命名空间。

## 使用 AWS CLI 查看查询指标
<a name="query-metrics-viewing-cli"></a>

**使用 AWS CLI 查看指标**
+ 请执行以下操作之一：
  + 要列出 Athena 的指标，请打开命令提示符，然后使用以下命令：

    ```
    aws cloudwatch list-metrics --namespace "AWS/Athena"
    ```
  + 要列出所有可用的指标，请使用以下命令：

    ```
    aws cloudwatch list-metrics"
    ```

## Athena 的 CloudWatch 指标与维度列表
<a name="athena-cloudwatch-metrics-table"></a>

如果您在 Athena 中启用了 CloudWatch 指标，则它会按工作组将以下指标发送到 CloudWatch。以下指标使用 `AWS/Athena` 命名空间。


| 指标名称 | 说明 | 
| --- | --- | 
| DPUAllocated |  在容量预留中预置的用于运行查询的 DPU（数据处理单元）总数。  | 
| DPUConsumed | 在预留的给定时间内，处于 RUNNING 状态的查询主动消耗的 DPU 数量。只有当工作组与容量预留关联并且包括与预留关联的所有工作组时，才会发出此指标。如果将工作组从一个预留转移到另一个预留，则指标将包含从该工作组属于第一个预留起的数据。有关容量预留的更多信息，请参阅[管理查询处理容量](capacity-management.md)。 | 
| DPUCount | 查询消耗的最大 DPU 数量，仅在查询完成时发布一次。只有工作组附加到了容量预留，才会发出此指标。 | 
| EngineExecutionTime |  运行查询所花费的毫秒数。  | 
| ProcessedBytes |  Athena 为每个 DML 查询扫描的字节数。对于已取消的查询（由用户取消，或者因为达到限制而自动取消），此指标包含在取消时间之前扫描的数据量。对于 DDL 或 CTAS 查询，不会报告此指标。  | 
| QueryPlanningTime | Athena 计划查询处理流程所花费的毫秒数。这包括从数据来源检索表分区所花费的时间。请注意，由于查询引擎执行查询计划，因此查询计划时间是 EngineExecutionTime 的子集。 | 
| QueryQueueTime | 查询在查询队列中等待资源所花的毫秒数。请注意，如果发生临时错误，则可以自动将查询添加回队列。 | 
| ServicePreProcessingTime | 在将查询提交给查询引擎之前，Athena 用于预处理查询的毫秒数。 | 
| ServiceProcessingTime | 查询引擎执行完查询后，Athena 处理查询结果所耗费的毫秒数。 | 
| TotalExecutionTime | Athena 运行 DDL 或 DML 查询所花费的毫秒数。TotalExecutionTime 包括 QueryQueueTime、 QueryPlanningTime、EngineExecutionTime 和 ServiceProcessingTime。 | 

Athena 的指标具有以下维度。


| 维度 | 说明 | 
| --- | --- | 
| CapacityReservation |  用于执行查询的容量预留的名称（如适用）。如果不使用容量预留，此维度不会返回任何数据。  | 
| QueryState |  查询状态。 有效统计数据：SUCCEEDED（成功）、FAILED（失败）或 CANCELED（已取消）。  | 
| QueryType |  查询类型。 有效统计数据：`DDL`、`DML` 或 `UTILITY`。运行的查询语句的类型。`DDL` 表示 DDL（数据定义语言）查询语句。`DML` 表示 DML（数据操作语言）查询语句，例如 `CREATE TABLE AS SELECT`。`UTILITY` 表示 DDL 和 DML 以外的查询语句，例如 `SHOW CREATE TABLE` 或 `DESCRIBE TABLE`。  | 
| 工作组 |  工作组的名称。  | 

# 使用 CloudWatch 监控 Athena 使用情况指标
<a name="monitoring-athena-usage-metrics"></a>

您可以使用 CloudWatch 用量指标在 CloudWatch 图表和控制面板上显示当前服务使用情况，以展示您的账户对资源的使用情况。

对于 Athena，用量可用性指标对应于 Athena 的 AWS 服务 配额。您可以配置警报，以在用量接近服务配额时向您发出警报。有关 Athena 服务配额的更多信息，请参阅 [服务配额](service-limits.md)。有关 AWS 用量指标的更多信息，请参阅《*Amazon CloudWatch 用户指南*》中的 [AWS 用量指标](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Service-Quota-Integration.html)。

Athena 在 `AWS/Usage` 命名空间中发布以下指标。


|  指标名称  |  说明  | 
| --- | --- | 
|  `ResourceCount`  |  每个账户每个 AWS 区域 的所有已排队和正在执行的查询的总和，按查询类型（DML 或 DDL）分隔。最大值是此指标唯一有用的统计数据。 此指标每分钟定期发布。如果您没有运行任何查询，指标不会报告任何内容（甚至连 0 也不报告）。只有在获取指标时正在运行活动查询时才会发布该指标。  | 

以下维度用于优化由 Athena 发布的用量指标。


|  维度  |  说明  | 
| --- | --- | 
|  `Service`  |  包含该资源的 AWS 服务 的名称。对于 Athena，此维度的值为 `Athena`。  | 
|  `Resource`  |  正在运行的资源的类型。Athena 查询用量的资源值为 `ActiveQueryCount`。  | 
|  `Type`  |  正在报告的实体的类型。目前，Athena 用量指标的唯一有效值为 `Resource`。  | 
|  `Class`  |  所跟踪的资源的类。对于 Athena，`Class` 可以是 `DML` 或 `DDL`。  | 

## 在 CloudWatch 控制台中查看 Athena 资源使用情况指标
<a name="monitoring-athena-usage-metrics-cw-console"></a>

您可以使用 CloudWatch 控制台查看 Athena 用量指标图表，并配置告警以便在您的用量接近服务配额时提醒您。

**查看 Athena 资源用量指标**

1. 通过 [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) 打开 CloudWatch 控制台。

1. 在导航窗格中，依次选择 **Metrics**（指标）、**All metrics**（所有指标）。

1. 选择**使用情况**，然后选择**按 AWS 资源**。

   这将显示服务配额用量指标的列表。

1. 选中 **Athena** 和 **ActiveQueryCount** 旁边的复选框。

1. 选择**绘成图表的指标**选项卡。

   以上图表显示 AWS 资源的当前用量。

要了解如何向图表添加服务限额，以及设置警报以在接近服务限额时向您发送通知，请参阅《Amazon CloudWatch 用户指南》**中的 [可视化服务限额并设置警报](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Quotas-Visualize-Alarms.html)。有关设置每个工作组的用量限制的信息，请参阅 [配置每个查询和每个工作组的数据使用情况控制](workgroups-setting-control-limits-cloudwatch.md)。

# 使用 EventBridge 监控 Athena 查询事件
<a name="athena-events"></a>

您可以将 Amazon Athena 与 Amazon EventBridge 结合使用来接收有关查询状态的实时通知。当您提交的查询转换了状态时，Athena 将事件发布到 EventBridge，其中包含有关该查询状态转换的信息。您可以针对感兴趣的事件编写简单规则，并在事件匹配规则时执行自动化操作。例如，您可以创建在查询到达终端状态时调用 AWS Lambda 函数的规则。尽最大努力发出事件。

在为 Athena 创建事件规则之前，您应该先执行以下操作：
+ 熟悉 EventBridge 中的事件、规则和目标。有关更多信息，请参阅[什么是 Amazon EventBridge？](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html) 有关如何设置规则的更多信息，请参阅 [Getting started with Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-get-started.html)。
+ 创建要在您的事件规则中使用的目标。

**注意**  
Athena 目前提供了一种事件类型，即 Athena 查询状态更改，但可能会添加其他事件类型和详细信息。如果您以编程方式对事件 JSON 数据反序列化，则在添加了其他属性时，请确保应用程序已准备好处理未知属性。

## Athena 事件格式
<a name="athena-events-pattern"></a>

以下是 Amazon Athena 事件的基本模式。

```
{
    "source":[
        "aws.athena"
    ],
    "detail-type":[
        "Athena Query State Change"
    ],
    "detail":{
        "currentState":[
            "SUCCEEDED"
        ]
    }
}
```

## Athena 查询状态更改事件
<a name="athena-events-athena-query-state-change"></a>

以下示例显示 `currentState` 值为 `SUCCEEDED` 的 Athena 查询状态更改事件。

```
{
    "version":"0",
    "id":"abcdef00-1234-5678-9abc-def012345678",
    "detail-type":"Athena Query State Change",
    "source":"aws.athena",
    "account":"123456789012",
    "time":"2019-10-06T09:30:10Z",
    "region":"us-east-1",
    "resources":[

    ],
    "detail":{
        "versionId":"0",
        "currentState":"SUCCEEDED",
        "previousState":"RUNNING",
        "statementType":"DDL",
        "queryExecutionId":"01234567-0123-0123-0123-012345678901",
        "workgroupName":"primary",
        "sequenceNumber":"3"
    }
}
```

以下示例显示 `currentState` 值为 `FAILED` 的 Athena 查询状态更改事件。`athenaError` 数据块仅当 `currentState` 为 `FAILED` 时才会出现。有关 `errorCategory` 和 `errorType` 的值的信息，请参阅 [Athena 错误目录](error-reference.md)。

```
{
    "version":"0",
    "id":"abcdef00-1234-5678-9abc-def012345678",
    "detail-type":"Athena Query State Change",
    "source":"aws.athena",
    "account":"123456789012",
    "time":"2019-10-06T09:30:10Z",
    "region":"us-east-1",
    "resources":[ 
    ],
    "detail":{
        "athenaError": {
            "errorCategory": 2.0, //Value depends on nature of exception
            "errorType": 1306.0, //Type depends on nature of exception
            "errorMessage": "Amazon S3 bucket not found", //Message depends on nature of exception
            "retryable":false //Retryable value depends on nature of exception
        },
        "versionId":"0",
        "currentState": "FAILED",
        "previousState": "RUNNING",
        "statementType":"DML",
        "queryExecutionId":"01234567-0123-0123-0123-012345678901",
        "workgroupName":"primary",
        "sequenceNumber":"3"
    }
}
```

### 输出属性
<a name="athena-events-query-state-change-output-properties"></a>

JSON 输出包括以下属性。


****  

| 属性 | 说明 | 
| --- | --- | 
| athenaError | 仅当 currentState 为 FAILED 时才会出现。包含有关所发生错误的信息，例如错误类别、错误类型、错误消息以及是否可以重试导致错误的操作。每个字段的值取决于错误性质。有关 errorCategory 和 errorType 的值的信息，请参阅 [Athena 错误目录](error-reference.md)。 | 
| versionId | 详细对象的架构的版本号。 | 
| currentState | 事件发生时查询转换到的状态。 | 
| previousState | 事件发生时查询转换前的状态。 | 
| statementType | 运行的查询语句的类型。 | 
| queryExecutionId | 所运行查询的唯一标识符。 | 
| workgroupName | 在其中运行查询的工作组的名称。 | 
| sequenceNumber | 一个单调递增的数字，可用于对涉及单个查询运行的传入事件进行重复数据删除和排序。当针对同一个状态转换发布了重复的事件时，sequenceNumber 值相同。当查询多次经历状态转换（例如查询遇到极少发生的重新入队）时，您可以使用 sequenceNumber 对具有相同 currentState 和 previousState 值的事件进行排序。 | 

## 示例
<a name="athena-events-examples"></a>

以下示例将事件发布到您订阅的 Amazon SNS 主题。查询 Athena 时，您会收到一封电子邮件。该示例假定 Amazon SNS 主题存在，并且您已订阅该主题。

**将 Athena 事件发布到 Amazon SNS 主题**

1. 为 Amazon SNS 主题创建目标。向 EventBridge 事件的服务主体授予 `events.amazonaws.com` 权限以发布到您的 Amazon SNS 主题，如下例所示。

   ```
   {
       "Effect":"Allow",
       "Principal":{
           "Service":"events.amazonaws.com"
       },
       "Action":"sns:Publish",
       "Resource":"arn:aws:sns:us-east-1:111111111111:your-sns-topic"
   }
   ```

1. 使用 AWS CLI `events put-rule` 命令为 Athena 事件创建规则，如以下示例所示。

   ```
   aws events put-rule --name {ruleName} --event-pattern '{"source": ["aws.athena"]}'
   ```

1. 使用 AWS CLI `events put-targets` 命令将 Amazon SNS 主题目标附加到规则，如以下示例所示。

   ```
   aws events put-targets --rule {ruleName} --targets Id=1,Arn=arn:aws:sns:us-east-1:111111111111:your-sns-topic
   ```

1. 查询 Athena 并观察所调用的目标。您应该收到来自 Amazon SNS 主题的对应电子邮件。

## 将 AWS 用户通知服务 和 Amazon Athena 搭配使用
<a name="monitoring-user-notifications"></a>

您可以使用 [AWS 用户通知服务](https://docs.aws.amazon.com/notifications/latest/userguide/what-is.html) 来设置交付渠道，以获得有关 Amazon Athena 事件的通知。当事件与指定的规则匹配时，会收到通知。您可以通过多个渠道接收事件通知，包括电子邮件、[聊天应用程序中的 Amazon Q 开发者版](https://docs.aws.amazon.com/chatbot/latest/adminguide/what-is.html)聊天通知或 [AWS Console Mobile Application](https://docs.aws.amazon.com/consolemobileapp/latest/userguide/what-is-consolemobileapp.html) 推送通知。您还可以在[控制台通知中心](https://console.aws.amazon.com/notifications/)查看通知。用户通知服务 支持聚合，这可以减少在具体事件期间收到的通知数量。

有关更多信息，请参阅 [AWS 用户通知服务 用户指南](https://docs.aws.amazon.com/notifications/latest/userguide/what-is.html)。**

# 配置每个查询和每个工作组的数据使用情况控制
<a name="workgroups-setting-control-limits-cloudwatch"></a>

 Athena 允许您设置两种类型的成本控制：每个查询限制和每个工作组限制。对于每个工作组，您可以设置一个每个查询限制和多个每个工作组限制。
+ **每个查询控制限制**用于指定扫描的每个查询的数据总量。如果工作组中运行的任何查询超出限制值，则该查询将取消。在工作组中您只能创建一个每个查询控制限制，该限制适用于工作组中运行的每个查询。如果您需要进行更改，可编辑限制。有关详细步骤，请参阅[创建每个查询数据使用控制](#configure-control-limit-per-query)。
+ **工作组范围内数据使用控制限制**用于指定在指定时间段内，针对该工作组中运行的所有查询扫描的数据总量。您可以创建多个每个工作组限制。通过工作组范围内查询限制，您可以对工作组中运行的查询所扫描的数据设置每小时或每日聚合的多个阈值。

  如果扫描的数据聚合量超出阈值，那么您可以将通知推送到 Amazon SNS 主题。要如此做，您需要在 Athena 控制台中配置 Amazon SNS 警报和操作，以便当达到限制值时通知管理员。有关详细步骤，请参阅[创建每个工作组数据使用控制](#configure-control-limit-per-workgroup)。您还可以从 CloudWatch 控制台，对 Athena 发布的任何指标创建告警和操作。例如，您可以对失败的查询次数设置警报。如果数量超出特定阈值，此警报可以触发向管理员发送电子邮件。如果超出限制值，操作将向指定用户发送 Amazon SNS 警报通知。

  您可以采取的其他操作：
  + 调用 Lambda 函数。有关更多信息，请参阅《*Amazon Simple Notification Service 开发人员指南*》中的[使用 Amazon SNS 通知调用 Lambda 函数](https://docs.aws.amazon.com/sns/latest/dg/sns-lambda-as-subscriber.html)。
  + 禁用工作组，以停止运行任何后续查询。要查看步骤，请参阅[启用或禁用工作组](workgroups-enabled-disabled.md)。

每个查询限制和每个工作组限制是相互独立的。只要超出任一限制，就会执行指定操作。如果两个或多个用户在同一工作组中同时运行查询，那么有可能每个查询未超出任何指定的限制，但扫描的数据总量超出了每个工作组的数据使用限制。在这种情况下，会向用户发送 Amazon SNS 告警。

## 创建每个查询的数据使用情况控制
<a name="create-a-per-query-data-usage-control"></a><a name="configure-control-limit-per-query"></a>

**创建每个查询数据使用控制**

每个查询控制限制用于指定扫描的每个查询的数据总量。如果工作组中运行的任何查询超出限制值，则该查询将取消。取消的查询将按照 [Amazon Athena 定价](https://aws.amazon.com/athena/pricing/)进行计费。
**注意**  
当查询被取消或失败时，Athena 可能已将部分结果写入 Amazon S3。在这种情况下，Athena 不会从存储结果的 Amazon S3 前缀中删除部分结果。您必须删除带有部分结果的 Amazon S3 前缀。Athena 使用 Amazon S3 分段上传来写入数据 Amazon S3。我们建议您设置存储桶生命周期策略，以便当查询失败时终止分段上传。有关更多信息，请参阅《Amazon Simple Storage Service 用户指南**》中的 [使用存储桶生命周期策略中止未完成的分段上传](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config)。
在某些情况下，Athena 可能会自动重试查询执行。在大多数情况下，这些查询能够成功完成，并将查询 ID 标记为 `Completed`。这些查询可能在初始尝试时写入了部分结果，并且可能会生成不完整的分段上传。

在工作组中您只能创建一个每个查询控制限制，该限制适用于工作组中运行的每个查询。如果您需要进行更改，可编辑限制。

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 在导航窗格中，选择 **Workgroups**（工作组）。

1. 从列表中选择工作组的名称。

1. 在**执行控制**选项卡上，选择**编辑控件**。

1. 编辑**扫描数据限制**的值。
   + 指定一个介于 10MB（最小值）与 7EB（最大值）之间的值。
   + 从下拉列表中选择单位值（例如，**千字节 KB** 或 **艾字节 EB**）。
**注意**  
如果超出限制，默认操作为取消查询。此设置不可更改。

1. 选择**保存**立即应用您的更改。

## 创建或编辑每个工作组的数据使用情况提示
<a name="create-a-per-workgroup-data-usage-alert"></a><a name="configure-control-limit-per-workgroup"></a>

**创建或编辑每个工作组的数据使用提示**

当工作组中运行的查询在特定时间段内扫描指定数量的数据时，可以设置多个提示阈值。提示使用 Amazon CloudWatch 发出告警，并适用于工作组中的所有查询。达到阈值后，您可以让 Amazon SNS 向指定的用户发送电子邮件。达到阈值时，查询不会自动取消。

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 如果控制台导航窗格不可见，请选择左侧的扩展菜单。

1. 在导航窗格中，选择 **Workgroups**（工作组）。

1. 从列表中选择工作组的名称。

1. 选择 **Edit**（编辑）以编辑工作组设置。

1. 向下滚动到并展开 **Workgroup data usage alerts - optional**（工作组数据使用提示 - 可选）。

1. 选择 **Add alert**（添加提示）。

1. 对于 **Data usage threshold configuration**（数据使用阈值配置），指定以下值：
   + 对于 **Data threshold**（数据阈值），指定数字，然后从下拉列表中选择单位值。
   + 对于 **Time period**（时间段），从下拉列表中选择时间段。
   + 对于 **SNS topic selection**（SNS 主题选择），从下拉列表中选择 Amazon SNS 主题。或者，选择 **Create SNS topic**（创建 SNS 主题）直接转至 [Amazon SNS 控制台](https://console.aws.amazon.com/sns/v2/home)，创建 Amazon SNS 主题，并为 Athena 账户中的用户之一设置该主题的订阅。有关更多信息，请参阅 *Amazon Simple Notification Service 开发人员指南*中的 [Amazon SNS 入门](https://docs.aws.amazon.com/sns/latest/dg/sns-getting-started.html)。

1. 如果正在创建新提示，则选择 **Add alert**（添加提示）；如果要保存现有的提示，则选择 **Save**（保存）。

# 使用 Athena 工作组 API
<a name="workgroups-api-list"></a>

以下是用于 Athena 工作组的部分 REST API 操作。在下列所有操作（`ListWorkGroups` 除外）中，都必须指定一个工作组。在 `StartQueryExecution` 等其他操作中，工作组参数是可选的，且此处未列出对应操作。有关操作的完整列表，请参阅 [Amazon Athena API 参考](https://docs.aws.amazon.com/athena/latest/APIReference/)。
+  [CreateWorkGroup](https://docs.aws.amazon.com/athena/latest/APIReference/API_CreateWorkGroup.html) 
+  [DeleteWorkGroup](https://docs.aws.amazon.com/athena/latest/APIReference/API_DeleteWorkGroup.html) 
+  [GetWorkGroup](https://docs.aws.amazon.com/athena/latest/APIReference/API_GetWorkGroup.html) 
+  [ListWorkGroups](https://docs.aws.amazon.com/athena/latest/APIReference/API_ListWorkGroups.html) 
+  [UpdateWorkGroup](https://docs.aws.amazon.com/athena/latest/APIReference/API_UpdateWorkGroup.html) 



# 对工作组错误进行故障排除
<a name="workgroups-troubleshooting"></a>

按照以下提示进行工作组故障排除。
+ 检查您账户中各个用户的权限。他们必须可访问查询结果的位置，以及要从中运行查询的工作组。如果他们要切换工作组，那么同时需要两个工作组的权限。有关信息，请参阅[使用 IAM 策略控制工作组访问](workgroups-iam-policy.md)。
+ 请注意 Athena 控制台中的上下文，以查看您要在哪一工作组中运行查询。如果您使用驱动程序，请确保设置为您需要的工作组。有关信息，请参阅[为查询指定工作组](specify-wkgroup-to-athena-in-which-to-run-queries.md)。
+ 如果您使用 API 或驱动程序运行查询，则必须使用以下方法之一指定查询结果位置：对于个人查询，使用 [OutputLocation](https://docs.aws.amazon.com/athena/latest/APIReference/API_ResultConfiguration.html#athena-Type-ResultConfiguration-OutputLocation)（客户端）。在工作组中，使用 [WorkGroupConfiguration](https://docs.aws.amazon.com/athena/latest/APIReference/API_WorkGroupConfiguration.html)。如果没有以任何一种方法指定位置，Athena 将在查询运行时发布错误。
+ 如果您使用工作组设置覆盖客户端设置，您可能会遇到有关查询结果位置的错误。例如，工作组用户可能没有相应权限，不能在 Amazon S3 中的工作组位置存储查询结果。在这种情况下，添加必需的权限。
+ 工作组会导致 API 操作的行为发生变化。要调用以下现有的 API 操作，要求您账户中的用户在 IAM 中对从中进行调用的工作组具有基于资源的权限。如果没有对工作组和工作组操作的权限，则下列 API 操作会引发 `AccessDeniedException`：**CreateNamedQuery**、**DeleteNamedQuery**、**GetNamedQuery**、**ListNamedQueries**、**StartQueryExecution**、**StopQueryExecution**、**ListQueryExecutions**、**GetQueryExecution**、**GetQueryResults** 和 **GetQueryResultsStream**（此 API 操作仅可与驱动程序一起使用，且不得通过其他方式供公众使用）。有关更多信息，请参阅《服务授权参考》**中的 [Amazon Athena 的操作、资源和条件键](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonathena.html)。

  调用 **BatchGetQueryExecution** 和 **BatchGetNamedQuery** API 操作时，仅会返回在用户可访问的工作组中运行的那些查询的相关信息。如果用户不可访问工作组，这些 API 操作会在未处理 ID 的列表中返回未授权的查询 ID。有关更多信息，请参阅 [使用 Athena 工作组 API](workgroups-api-list.md)。
+ 如果将从中运行查询的工作组已使用[强制实施的查询结果位置](workgroups-settings-override.md)配置，不要为 CTAS 查询指定 `external_location`。在此例中，Athena 将使指定了 `external_location` 的查询失败并发布错误。例如，如果您覆盖查询结果位置的客户端设置，强制工作组使用其自己的位置，此查询失败：`CREATE TABLE <DB>.<TABLE1> WITH (format='Parquet', external_location='s3://amzn-s3-demo-bucket/test/') AS SELECT * FROM <DB>.<TABLE2> LIMIT 10;`

您可能会看到以下错误。下表给出与工作组相关的部分错误以及建议的解决方案的列表。


**工作组错误**  

| 错误 | 出错情况... | 
| --- | --- | 
|  query state CANCELED.（查询状态已取消。） Bytes scanned limit was exceeded.（已超出扫描字节数限制。）  | 查询超过查询数据限制并已取消。请考虑重写查询以使其读取更少的数据，或联系您的账户管理员。 | 
|  User: arn:aws:iam::123456789012:user/abc is not authorized to perform: athena:StartQueryExecution on resource: arn:aws:athena:us-east-1:123456789012:workgroup/workgroupname （用户：arn:aws:iam::123456789012:user/abc 无权执行：资源上的 athena：StartQueryExecution：arn:aws:athena:us-east-1:123456789012:workgroup/workgroupname）  | 用户在一个工作组中运行查询，但不可访问该工作组。更新您的策略以便可访问该工作组。 | 
|  INVALID\$1INPUT. WorkGroup <name> is disabled.（工作组 <name> 已禁用。）  | 用户在一个工作组中运行查询，但该工作组已被禁用。您的工作组可由您的管理员禁用。也有可能是您没有对其的访问权限。在这两种情况下，与有权访问以修改工作组的管理员联系。 | 
|  INVALID\$1INPUT. WorkGroup <name> is not found.（未找到工作组 <name>。）  | 用户在一个工作组中运行查询，但该工作组不存在。如果工作组已被删除，就会发生这种情况。切换到另一工作组以运行查询。 | 
|  InvalidRequestException: when calling the StartQueryExecution operation: No output location provided.（InvalidRequestException：调用 StartQueryExecution 操作时：未提供输出位置。） An output location is required either through the Workgroup result configuration setting or as an API input.（需要通过工作组结果配置设置或作为 API 输入的输出位置。）  |  用户使用 API 运行查询，但未指定查询结果的位置。您必须使用以下两种方法之一为查询结果设置输出位置：对于单独查询，使用 [OutputLocation](https://docs.aws.amazon.com/athena/latest/APIReference/API_ResultConfiguration.html#athena-Type-ResultConfiguration-OutputLocation)（客户端）；对于工作组，使用 [WorkGroupConfiguration](https://docs.aws.amazon.com/athena/latest/APIReference/API_WorkGroupConfiguration.html)。  | 
|   The Create Table As Select query failed because it was submitted with an 'external\$1location' property to an Athena Workgroup that enforces a centralized output location for all queries.（“根据选择创建表”查询失败，因为其与“external\$1location”属性一同提交给强制执行所有查询集中输出位置的 Athena 工作组。） Please remove the 'external\$1location' property and resubmit the query.（请删除“external\$1location”属性并重新提交查询。）   | 如果从中运行查询的工作组已使用[强制实施的查询结果位置](workgroups-settings-override.md)配置，而且您为 CTAS 查询指定 external\$1location。在这种情况下，请删除 external\$1location 并重新运行查询。 | 
| Cannot create prepared statement prepared\$1statement\$1name.（无法创建预处理语句 prepared\$1statement\$1name。） The number of prepared statements in this workgroup exceeds the limit of 1000.（该工作组中的预处理语句数已超过 1000 的限制。） | 工作组中的预处理语句数已超过 1000 的限制。为解决此问题，请使用 [DEALLOCATE PREPARE](sql-deallocate-prepare.md) 从工作组中删除一条或多条预处理语句。或者，创建新工作组。 | 

# 管理查询处理容量
<a name="capacity-management"></a>

可以使用容量预留为您在 Athena 中运行的查询指定专用无服务器处理容量。可通过容量预留，利用工作负载管理功能，帮助您控制和扩展最重要的工作负载并确定其优先级。例如，您可以添加容量以控制可同时运行的查询数量，选择可以使用容量的工作负载，并在工作负载之间共享容量。容量为无服务器，完全由 Athena 托管，只要您需要，可以保留任意长的时间。设置简单，无需更改 SQL 查询。

要获取查询的处理容量，可创建容量预留，指定所需的数据处理器（DPU）数，并为预留分配一个或多个工作组。

在您使用容量预留时，工作组至关重要。工作组可用于将查询分为不同的逻辑分组或使用案例。可通过容量预留，有选择地将容量分配给工作组，从而控制每个工作组的查询行为方式和计费方式。有关工作组的更多信息，请参阅 [使用工作组控制查询访问和成本](workgroups-manage-queries-control-costs.md)。

通过将工作组分配给容量预留，您可以优先处理这些查询，因为这些查询基于您的预留容量运行，不计入您的 DDL 和 DML 查询配额。例如，您可以向工作组分配用于时间敏感型财务报告查询的容量，以将这些查询与另一个工作组中不太重要的查询隔离开来。这可以为关键工作负载提供可预测的查询执行，同时允许其他工作负载独立运行。

您可以同时使用容量预留和工作组来满足不同的需求。下面是一些示例方案：
+ **隔离重要查询**：为确保重要工作负载在需要时拥有所需的容量，请创建容量预留并将其工作组分配给预留。只有来自已分配工作组的查询才使用预留的处理能力。例如，为了确保可靠地执行支持生产应用程序的查询，可以将这些查询的生产工作组分配给容量预留。开发查询时，请使用与预留无关联的单独工作组，并在准备就绪后将查询移至生产工作组。
+ **在相似工作负载间共享容量**：多个工作负载可共享同一预留的容量。这使您可以预测这些工作负载的成本和控制其并发性。例如，如果您有能够容忍查询执行启动时间延迟的计划工作负载，则可以将其工作组分配给单个预留。这可以为在同一账户中运行的交互式查询腾出您的 DDL 和 DML 查询配额，从而确保这些查询以最小的延迟启动。

## 了解 DPU
<a name="capacity-management-understanding-dpus"></a>

容量以数据处理器（DPU）数进行度量。DPU 表示 Athena 代表您访问和处理数据时所使用的无服务器计算和内存资源。一个 DPU 通常提供 4 个 vCPU 和 16GB 内存。持有的 DPU 数会影响可以并发运行的查询数。例如，具有 256 个 DPU 的预留所支持的并发查询数大约是具有 128 个 DPU 的预留的两倍。

有关估算容量需求的信息，请参阅 [确定容量要求](capacity-management-requirements.md)。有关定价信息，请参阅 [Amazon Athena 定价](https://aws.amazon.com/athena/pricing/)。

## 注意事项和限制
<a name="capacity-management-considerations-limitations"></a>
+ 您可以在同一账户中同时使用容量预留和基于扫描数据的按查询计费。
+ 在容量预留上运行的查询不会计入您的 DDL 和 DML 查询配额。
+ 如果您的容量忙于处理其他查询，则新提交的查询将排队等候，直到容量可用为止。队列中允许的最长时间为 10 小时。
+ 一个工作组一次只能分配给一个容量预留。您总共可以为单个预留分配 20 个工作组。当您将多个工作组分配给预留时，容量将在各工作组之间共享，并根据查询的提交顺序分配给查询。由于 Athena 向查询动态分配容量的方式，执行顺序可能会有所不同。
+ Athena 会根据查询的复杂程度自动为 DML 查询分配 4 到 124 个 DPU。每个 DDL 查询消耗 4 个 DPU。请参阅以下主题了解更多信息：
  + [确定容量要求](capacity-management-requirements.md)
  + [控制容量使用](capacity-management-control-capacity-usage.md)
+ 每个容量预留所需的最低 DPU 数量为 4。有关定价信息，请参阅 [Amazon Athena 定价](https://aws.amazon.com/athena/pricing/)。
+ 您最多可以创建 100 个容量预留，每个账户和区域最多可以具有 1000 个 DPU。如果您的使用案例需要超过 1000 个 DPU，请联系 [athena-feedback@amazon.com](mailto:athena-feedback@amazon.com?subject=Athena Provisioned Capacity DPU Limit Request)。
+ 容量请求无法保证，并且可能需要花费 30 分钟时间完成。容量无法转移到另一个容量预留、AWS 账户或 AWS 区域。
+ `DPUConsumed` CloudWatch 指标是按工作组计算，而不是按预留量计算。因此，如果将工作组从一个预留转移到另一个预留，则 `DPUConsumed` 指标将包含从该工作组属于第一个预留起的数据。有关在 Athena 中使用 CloudWatch 指标的更多信息，请参阅[使用 CloudWatch 监控 Athena 查询指标](query-metrics-viewing.md)。
+ 要删除已分配给预留的工作组，请先将该工作组从预留中移除。
+ 不支持配置为使用 Apache Spark 的工作组。
+ 以下商业 AWS 区域不提供容量预留：
  + 以色列（特拉维夫）
  + 中东（阿联酋）：
  + 中东（巴林）
  + 亚太地区（新西兰）

**Topics**
+ [了解 DPU](#capacity-management-understanding-dpus)
+ [注意事项和限制](#capacity-management-considerations-limitations)
+ [确定容量要求](capacity-management-requirements.md)
+ [创建容量预留](capacity-management-creating-capacity-reservations.md)
+ [控制容量使用](capacity-management-control-capacity-usage.md)
+ [自动调整容量](capacity-management-automatically-adjust-capacity.md)
+ [管理预留](capacity-management-managing-reservations.md)
+ [容量预留的 IAM policy](capacity-reservations-iam-policy.md)
+ [Athena 容量预留 API](capacity-management-api-list.md)

# 确定容量要求
<a name="capacity-management-requirements"></a>

在创建容量预留之前，您可以估算所需的容量，以向其分配正确的 DPU 数。在使用预留后，您可能需要检查预留的容量是不足还是过剩。本主题介绍了可用于进行这些估算的方法，同时介绍了一些用于评估使用量和成本的 AWS 工具。

**Topics**
+ [估算所需容量](#capacity-management-requirements-estimating)
+ [表明需要更多容量的迹象](#capacity-management-requirements-insufficient-capacity)
+ [检查是否存在空闲容量](#capacity-management-requirements-idle-capacity)
+ [监控 DPU 消耗](#capacity-management-requirements-monitoring-dpu-consumption)

## 估算所需容量
<a name="capacity-management-requirements-estimating"></a>

在估算容量需求时，建议考虑两个方面：特定查询可能需要的容量数量以及大体上可能需要的容量数量。

### 估算每个查询的容量需求
<a name="capacity-management-requirements-estimating-query"></a>

要确定查询可能需要的 DPU 数，可遵循以下准则：
+ DDL 查询消耗 4 个 DPU。
+ DML 查询会消耗 4 到 124 个 DPU。

Athena 会在提交查询时确定 DML 查询所需的 DPU 数。该数量取决于数据大小、存储格式、查询构造和其他因素。通常，Athena 会尝试选择最低且最高效的 DPU 数。如果 Athena 确定查询需要更高的计算能力才能成功完成，则它会增加分配给查询的 DPU 数。

### 估算特定于工作负载的容量需求
<a name="capacity-management-requirements-estimating-workload"></a>

要确定同时运行多个查询可能需要的容量数量，请遵循下表中的常规准则：


****  

| 并发查询 | 所需 DPU 数量 | 
| --- | --- | 
| 10 | 大于等于 40 | 
| 20 | 大于等于 96 | 
| 大于等于 30 | 大于等于 240 | 

请注意，所需的实际 DPU 数量取决于您的目标和分析模式。例如，如果您希望查询立即开始而不排队，确定您的并发查询需求峰值，然后相应地预置 DPU 数量。

您可以配置低于峰值需求的 DPU 数，但是在出现需求峰值时，可能会导致排队。出现排队时，Athena 会将您的查询搁置在队列中，并在容量可用时运行这些查询。

如果您的目标是在固定预算内运行查询，则可以使用 [AWS 定价计算器](https://calculator.aws/#/addService/Athena)来确定适合自己预算的 DPU 数。

最后，请记住，数据大小、存储格式和查询写入方式都会影响查询所需的 DPU 数量。要提高查询性能，可对数据进行压缩或分区，或者将其转换为列格式。有关更多信息，请参阅 [优化 Athena 性能](performance-tuning.md)。

## 表明需要更多容量的迹象
<a name="capacity-management-requirements-insufficient-capacity"></a>

容量不足错误消息和查询排队均表明您分配的容量不足。

如果您的查询失败并显示容量不足错误消息，则容量预留的 DPU 数过低，无法满足查询工作。例如，如果您的预留包含 24 个 DPU，并且运行的查询需要超过 24 个 DPU，则查询将失败。要监控此查询错误，可以使用 Athena 的 [EventBridge 事件](athena-events.md)。尝试添加更多 DPU，并重新运行查询。

如果许多查询在排队，这意味着您的容量已被其他查询完全占据。要减少排队时间，请执行以下操作之一：
+ 向预留添加 DPU 以提高查询并发性。
+ 从预留中移除工作组，以释放容量供其他查询使用。

要检查查询排队是否过多，使用容量预留中工作组的 Athena 查询队列时间 [CloudWatch 指标](query-metrics-viewing.md)。如果该值高于您的首选阈值，则可以将 DPU 添加至容量预留。

## 检查是否存在空闲容量
<a name="capacity-management-requirements-idle-capacity"></a>

要检查是否存在空闲容量，您可以减少预留中的 DPU 数或增加其工作负载，然后观察结果。

**检查是否存在空闲容量**

1. 请执行以下操作之一：
   + 减少预留中的 DPU 数（减少可用资源）
   + 向预留添加工作组（增加工作负载）

1. 使用 [CloudWatch](query-metrics-viewing.md) 测量查询队列时间。

1. 如果队列时间超过所需水平，执行以下任一操作
   + 移除工作组
   + 将 DPU 添加至容量预留

1. 在每次更改后，都要检查性能和查询队列时间。

1. 继续调整工作负载和/或 DPU 数以达到所需的平衡。

如果不希望在首选时间段范围之外保持容量，则可以[取消](capacity-management-cancelling-a-capacity-reservation.md)预留并稍后创建另一个预留。但是，即使您最近取消了另一个预留的容量，也无法保证会请求新的容量，并且创建新的预留需要花费一些时间。

## 监控 DPU 消耗
<a name="capacity-management-requirements-monitoring-dpu-consumption"></a>

查询运行后，您可以查看查询消耗的 DPU，以帮助优化容量估算。Athena 通过控制台、API 操作和 CloudWatch 提供 DPU 消耗指标。此信息可帮助您识别消耗资源超出或低于预期的查询，并根据实际数据优化容量分配。有关查看和跟踪 DPU 消耗的详细信息，请参阅[监控 DPU 使用情况](capacity-management-control-capacity-usage.md#capacity-management-monitor-dpu-usage)。

## 用于评估容量需求和成本的工具
<a name="capacity-management-requirements-tools"></a>

您可以使用 AWS 中的以下服务和功能测量 Athena 的使用情况和成本。

### CloudWatch 指标
<a name="capacity-management-requirements-tools-cloudwatch-metrics"></a>

您可以将 Athena 配置为在工作组级别下向 Amazon CloudWatch 发布查询相关指标。为工作组启用指标后，工作组查询的指标将在 Athena 控制台的工作组详细信息页面中显示。

有关发布到 CloudWatch 的 Athena 指标及其维度的信息，请参阅 [使用 CloudWatch 监控 Athena 查询指标](query-metrics-viewing.md)。

### CloudWatch 使用情况指标
<a name="capacity-management-requirements-tools-cloudwatch-usage-metrics"></a>

您可以使用 CloudWatch 用量指标在 CloudWatch 图表和控制面板上显示当前服务使用情况，以展示您的账户对资源的使用情况。对于 Athena，用量可用性指标对应于 AWS [服务限额](service-limits.md)。您可以配置警报，以在用量接近服务配额时向您发出警报。

有关更多信息，请参阅 [使用 CloudWatch 监控 Athena 使用情况指标](monitoring-athena-usage-metrics.md)。

### Amazon EventBridge 事件
<a name="capacity-management-requirements-tools-eventbridge-events"></a>

您可以将 Amazon Athena 与 Amazon EventBridge 结合使用来接收有关查询状态的实时通知。当已提交查询的状态发生变化时，Athena 将向 EventBridge 发布一个包含有关查询状态转换的信息的事件。您可以针对感兴趣的事件编写简单规则，并在事件匹配规则时执行自动化操作。

有关详细信息，请参阅以下资源：
+ [使用 EventBridge 监控 Athena 查询事件](athena-events.md)
+ [什么是 Amazon EventBridge？](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html)
+ [Amazon EventBridge 事件](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-events.html) 

### 标签
<a name="capacity-management-requirements-tools-tags"></a>

在 Athena 中，容量预留支持标签。每个标签均包含一个键和一个值。要在 Athena 中跟踪成本，您可以使用 AWS 生成的成本分配标签。AWS 使用成本分配标签对[成本和使用率报告](https://docs.aws.amazon.com/cur/latest/userguide/what-is-cur.html)上的资源成本进行组织。这样您可以更轻松地对 AWS 成本进行分类和跟踪。要激活 Athena 的成本分配标签，您可以使用 [AWS 账单与成本管理 控制台](https://console.aws.amazon.com/billing/)。

有关详细信息，请参阅以下资源：
+ [标记 Athena 资源](tags.md)
+ [激活 AWS 生成的成本分配标签](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/activate-built-in-tags.html)
+ [使用 AWS 成本分配标签](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html)

# 创建容量预留
<a name="capacity-management-creating-capacity-reservations"></a>

首先，创建一个具有所需 DPU 数的容量预留，然后分配一个或多个将使用该容量进行查询的工作组。您可以稍后根据需要调整容量，以实现更一致的性能或优化管理成本。有关估算容量需求的信息，请参阅 [确定容量要求](capacity-management-requirements.md)。

**重要**  
容量请求无法保证，并且可能需要花费 30 分钟时间完成。

**创建容量预留**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 如果控制台导航窗格不可见，请选择左侧的扩展菜单。

1. 选择**管理**、**容量预留**。

1. 选择**创建容量预留**。

1. 在**创建容量预留**页面的**容量预留名称**中，输入相应的名称。名称必须唯一，长度介于 1 到 128 个字符之间，并且只能使用字符 a-z、A-Z、0-9、\$1（下划线）、.（句点）和 -（连字符）。在创建预留后无法更改其名称。

1. 对于 **DPU**，选择或输入所需的数据处理器（DPU）数，增量为 4。有关更多信息，请参阅 [了解 DPU](capacity-management.md#capacity-management-understanding-dpus)。

1. （可选）展开**标签**选项，然后选择**添加新标签**添加一个或多个要与容量预留资源相关联的自定义键/值对。有关更多信息，请参阅 [标记 Athena 资源](tags.md)。

1. 选择**审核**。

1. 在**确认创建容量预留**提示中，确认 DPU 数、AWS 区域 和其他信息。如果您接受这些内容，请选择**提交**。

   在详细信息页面上，您的容量预留**状态**显示为**待处理**。当您的预留容量可供运行查询时，其状态将显示为**活动**。

此时，您可以随时向预留添加一个或多个工作组。要查看步骤，请参阅[向预留添加工作组](capacity-management-adding-workgroups-to-a-reservation.md)。

# 控制容量使用
<a name="capacity-management-control-capacity-usage"></a>

您可以通过设置最大或最小 DPU 控制来控制 Athena 分配给查询的 DPU 数量。您可以在工作组级别对其进行配置以建立所有查询的基准控制，也可以在单个查询级别进行精细控制。这使您可以直接控制查询性能、工作负载并发性和成本。
+ 设置最大 DPU 数时，查询不会消耗超出您指定的容量。这使得控制成本和工作负载并发性变得简单。例如，如果您的容量预留有 200 个 DPU，则将每次查询的最大 DPU 数设置为 8 可允许您同时运行 25 个查询。如果您将预留增加到 400 个 DPU，则可以同时运行 50 个查询。
+ 设置最小 DPU 数量时，可以确保使用所需的最低 DPU 数量执行查询。如果您事先了解查询的典型容量使用情况，这会很有帮助。

**注意**  
DPU 使用控制仅适用于使用容量预留执行的查询。

**注意**  
要对所有查询使用相同数量的 DPU，请对最小和最大 DPU 使用相同的值。

## 在工作组级别设置 DPU 控制
<a name="capacity-management-set-dpu-controls-workgroup-level"></a>

在工作组级别设置 DPU 控制以管理成本并控制所选工作组的工作负载性能。启用**覆盖客户端侧设置**后，在工作组级别设置的 DPU 控制适用于所有查询。

**使用控制台设置 DPU 控制**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 在导航窗格中，选择 **Workgroups**（工作组）。

1. 选择使用容量预留的工作组。

1. 在**执行控制**选项卡上，选择**编辑控件**。

1. 配置以下内容：
   + 对**每次查询的最小 DPU**，输入一个介于 4 到 124 之间的值，增量为 4。
   + 对**每次查询的最大 DPU**，输入一个介于 4 到 124 之间的值，增量为 4。

1. 选择**保存**。

1. （可选）选择**覆盖客户端侧设置**以强制执行这些设置并忽略查询级 DPU 配置。

**使用 AWS CLI 设置 DPU 控制**
+ 使用 `update-work-group` 命令设置工作组的 DPU 控制：

  ```
  aws athena update-work-group \
    --work-group my_workgroup \
    --configuration-updates '{
          "EngineConfiguration": {
              "Classifications": [
                  {
                      "Name": "athena-query-engine-properties",
                      "Properties": {
                          "max-dpu-count" : "24",
                          "min-dpu-count" : "12"
                          }
                      }
                  ]
          }}'
  ```

  如果将 `EnforceWorkGroupConfiguration` 设置为 `true`，则通过 [StartQueryExecution](https://docs.aws.amazon.com/athena/latest/APIReference/API_StartQueryExecution.html) 提交时工作组设置将覆盖查询级别指定的任何 DPU 控制。这样可以确保工作组中所有查询的资源分配保持一致。

## 使用单个查询设置 DPU 控制
<a name="capacity-management-set-dpu-controls-individual-queries"></a>

当您需要对具有不同资源要求的查询进行精细控制时，请设置查询级 DPU 控制。除非工作组启用**覆盖客户端侧设置**，否则查询级 DPU 控制优先于工作组级设置。

**使用控制台设置查询的 DPU 控制**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 在导航窗格中，选择**查询编辑器**。

1. 选择使用容量预留的工作组。

1. 选择**查询设置**选项卡。

1. 在**执行控制**部分，选择**编辑控件**。

1. 配置以下内容：
   + 对**每次查询的最小 DPU**，输入一个介于 4 到 124 之间的值，增量为 4。
   + 对**每次查询的最大 DPU**，输入一个介于 4 到 124 之间的值，增量为 4。

1. 选择**保存**。

**使用 AWS CLI 设置查询的 DPU 控制**
+ 将 `start-query-execution` 命令与 `engine-configuration` 参数一起使用：

  ```
  aws athena start-query-execution \
    --query-string "SELECT * FROM my_table LIMIT 10" \
    --work-group "my_workgroup" \
    --engine-configuration '{
      "Classifications": [ {
          "Name": "athena-query-engine-properties",
              "Properties": {
                  "max-dpu-count" : "32",
                  "min-dpu-count" : "8"
                  }
              }
          ]}'
  ```

查询级和工作组级 DPU 设置之间的关系取决于您的工作组配置：
+ 启用**覆盖客户端侧设置**后，工作组级 DPU 控制优先于任何查询级设置。这样可以确保指定工作组中所有查询的资源使用保持一致。
+ 未启用**覆盖客户端侧设置**时，查询级 DPU 控制优先于任何工作组级设置。这样可以灵活地优化单个查询。

如果您没有在任一级别指定 DPU 控制，Athena 会根据查询的复杂程度自动分配容量。

**注意**  
对于 DDL 查询，最小 DPU 数的最大值为 4。设置更高的 DDL 查询最小值会导致错误。

## 监控 DPU 使用情况
<a name="capacity-management-monitor-dpu-usage"></a>

查询完成后，您可以查看其 DPU 使用情况。Athena 通过控制台、API 操作和 CloudWatch 提供 DPU 使用情况指标。

**在控制台中查看 DPU 消耗**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 在导航窗格中，选择**查询编辑器**。

1. 查询完成后，可在查询结果容器中查看其**使用的 DPU** 值。

1. 要查看过去查询的 DPU 消耗，请执行以下操作：

   1. 在导航窗格中，选择**最近的查询**。

   1. 选择设置图标，将**使用的 DPU** 列添加到表格中（如果尚未显示）。

   1. 查看每个已完成查询的 DPU 消耗。

1. （可选）从**查询编辑器**中选择**查询统计数据**选项卡，然后查看**使用的 DPU**。

**使用 API 检索 DPU 消耗**

1. 使用以下 API 操作以编程方式检索 DPU 消耗：
   + `GetQueryExecution`：返回特定查询的执行详细信息
   + `BatchGetQueryExecution`：返回多个查询的执行详细信息

1. 使用 AWS CLI 的示例：

   ```
   aws athena get-query-execution \
     --query-execution-id "123e4567-e89b-12d3-a456-426614174000"
   ```

   响应包含 `Statistics` 对象中的 `DpuCount` 字段：

   ```
   {
     "QueryExecution": {
       "Statistics": {
         "DpuCount": 8
       }
     }
   }
   ```

**使用 CloudWatch 监控 DPU 使用情况**
+ Athena 将查询相关的指标发布到 CloudWatch，帮助您监控容量利用率和其他性能数据。要了解更多信息，请参阅[使用 CloudWatch 监控 Athena 查询指标](query-metrics-viewing.md)。

# 自动调整容量
<a name="capacity-management-automatically-adjust-capacity"></a>

使用 Athena 的自动扩缩解决方案，您可以根据工作负载利用率自动调整预留容量。当利用率超出您配置的阈值时，它会自动增加容量；当利用率较低时，它会自动减少容量，从而降低成本。您可以通过设置不同的利用率阈值、最小和最大 DPU 数量、扩缩增量和利用率评估频率来自定义其行为。这样便无需手动调整容量，同时帮助您在性能要求与成本优化之间取得平衡。

您可以使用 CloudFormation 模板部署此无服务器解决方案。它会创建一台 Step Functions 状态机，用于监控利用率指标并进行扩展决策。您可以进一步自定义模板或状态机以满足自己的特定需求。

要开始使用，请使用 Athena 控制台，在容量预留详细信息页面上选择**设置自动扩缩**，该页面会将您重定向到预加载模板的 CloudFormation。或者，您可以按照以下步骤操作。

## 先决条件
<a name="capacity-management-auto-scaling-prerequisites"></a>
+ 需要有效的容量预留
+ 需要部署 CloudFormation 堆栈和创建 Step Functions 资源的 IAM 权限

## 启动 CloudFormation 堆栈
<a name="capacity-management-auto-scaling-launch-stack"></a>

此自动 CloudFormation 模板部署了 Athena 容量预留自动扩缩解决方案。在启动堆栈之前，您必须完成[先决条件](#capacity-management-auto-scaling-prerequisites)中的相应步骤。

[https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?&templateURL=https:%2F%2Fathena-downloads.s3.us-east-1.amazonaws.com%2F%2Ftemplates%2F%2Fcapacity-reservation-scaling%2F%2Fstate-machine%2F%2Fathena-capacity-reservation-scaling-template-v1.1.yaml](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?&templateURL=https:%2F%2Fathena-downloads.s3.us-east-1.amazonaws.com%2F%2Ftemplates%2F%2Fcapacity-reservation-scaling%2F%2Fstate-machine%2F%2Fathena-capacity-reservation-scaling-template-v1.1.yaml) 

**启动自动扩缩解决方案**

1. 登录到 [AWS 管理控制台](https://console.aws.amazon.com/)，然后选择按钮以启动 `AWSAccelerator-InstallerStack` CloudFormation 模板。

1. 默认情况下，该模板在美国东部（弗吉尼亚州北部）启动。要在其他 AWS 区域启动此解决方案，请使用控制台导航栏中的区域选择器。

1. 在**创建堆栈**页面上，确认 **Amazon S3 URL** 文本框中已有模板 URL，然后选择**下一步**。

1. 在**指定堆栈详细信息**页面上，为您的解决方案堆栈分配一个名称。

1. 在**参数**下，检查该解决方案模板的参数，并根据需要进行修改。该解决方案使用以下默认值。  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/capacity-management-automatically-adjust-capacity.html)
**注意**  
所有 DPU 值必须是 4 的倍数，才能符合 Athena 的容量预留要求。

1. 选择 **Next**(下一步)。

1. 在**配置堆栈选项**页面上，请选择**下一步**。

1. 在**审核并创建**页面上，审核并确认设置。选中确认模板可创建 IAM 资源的复选框。

1. 选择**提交**以部署堆栈。

   您可以在 CloudFormation 控制台的**状态**列中查看堆栈的状态。您将在几分钟后收到 `CREATE_COMPLETE` 状态。

# 管理预留
<a name="capacity-management-managing-reservations"></a>

您可以在**容量预留**页面上查看和管理您的容量预留。您可以执行诸多管理任务，例如添加或减少 DPU、修改工作组分配以及标记或取消预留。

**查看和管理容量预留**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 如果控制台导航窗格不可见，请选择左侧的扩展菜单。

1. 选择**管理**、**容量预留**。

1. 在容量预留页面上，可以执行以下任务：
   + 要创建容量预留，请选择**创建容量预留**。
   + 使用搜索框按 DPU 的名称或数量筛选预留。
   + 选择状态下拉菜单以按容量预留状态（例如，**活动**或**已取消**）进行筛选。有关预留状态的更多信息，请参阅 [了解预留状态](#capacity-management-understanding-reservation-status)。
   + 要查看容量预留的详细信息，请选择预留链接。预留的详细信息页面包含用于[编辑容量](capacity-management-editing-capacity-reservations.md)、[添加工作组](capacity-management-adding-workgroups-to-a-reservation.md)、[删除工作组](capacity-management-removing-a-workgroup-from-a-reservation.md)和[取消](capacity-management-cancelling-a-capacity-reservation.md)预留的选项。
   + 要编辑预留（例如，通过添加或移除 DPU），请选择预留对应的按钮，然后选择**编辑**。
   + 要取消预订，请选择预留对应的按钮，然后选择**取消**。

## 了解预留状态
<a name="capacity-management-understanding-reservation-status"></a>

下表描述了容量预留的可能状态值。


****  

| Status | 说明 | 
| --- | --- | 
| 待处理 | Athena 正在处理您的容量请求。容量未就绪，无法运行查询。 | 
| 活跃 | 容量可用于运行查询。 | 
| 已失败 | 您的容量请求未成功完成。请注意，无法保证完成容量请求。失败的预留将计入您的账户 DPU 限制。要释放用量，必须取消预留。 | 
| 待更新 | Athena 正在处理预留更改。例如，在编辑预留以添加或删除 DPU 之后，就会出现该状态。 | 
| 正在取消 | Athena 正在处理取消预留请求。允许正在使用预留的工作组中仍在运行的查询完成，但工作组中的其他查询将使用按需（未预置）容量。 | 
| 已取消 |  容量预留取消已完成。已取消预留将在控制台中保留 45 天。45 天后，Athena 将删除该预留。在 45 天内，您不能重新利用或重复使用该预留，但是可以引用其标签并查看其详细信息以供历史参考。 无法保证已取消容量在未来可以重新预留。容量无法转移到另一个预留 AWS 账户 或 AWS 区域。  | 

## 了解活动 DPU 和目标 DPU
<a name="capacity-management-understanding-dpu-status"></a>

在 Athena 控制台的容量预留列表中，您的预留会显示两个 DPU 值：**活动 DPU** 和**目标 DPU**。
+ **活动 DPU** - 您的预留中可用于运行查询的 DPU 数。例如，如果您请求 100 个 DPU，并且您的请求已完成，则**活动 DPU** 会显示 **100**。
+ **目标 DPU** - 您的预留正在移至的 DPU 数。在创建预留时或者在等待增加或减少 DPU 数时，**目标 DPU** 显示的值与**活动 DPU** 不同。

例如，在您提交创建具有 24 个 DPU 的预留请求后，预留**状态**将为**待处理**，**活动 DPU** 将为 **0**，**目标 DPU** 将为 **24**。

如果您的预留具有 100 个 DPU，并且编辑您的预留以请求增加 20 个 DPU，则**状态**将为**待更新**，**活动 DPU** 将为 **100**，**目标 DPU** 将为 **120**。

如果您的预留具有 100 个 DPU，并且编辑您的预留以请求减少 20 个 DPU，则**状态**将为**待更新**，**活动 DPU** 将为 **100**，**目标 DPU** 将为 **80**。

在此类转换期间，Athena 会根据您的要求主动获取或减少 DPU 数。当**活动 DPU** 等于**目标 DPU** 时，表示已达到目标数字，并且没有待处理的更改。

要以编程的方式检索这些值，可以调用 [GetCapacityReservation](https://docs.aws.amazon.com/athena/latest/APIReference/API_GetCapacityReservation.html) API 操作。API 将**活动 DPU** 和**目标 DPU** 称为 `AllocatedDpus` 和 `TargetDpus`。

**Topics**
+ [了解预留状态](#capacity-management-understanding-reservation-status)
+ [了解活动 DPU 和目标 DPU](#capacity-management-understanding-dpu-status)
+ [编辑容量预留](capacity-management-editing-capacity-reservations.md)
+ [向预留添加工作组](capacity-management-adding-workgroups-to-a-reservation.md)
+ [从预留中移除工作组](capacity-management-removing-a-workgroup-from-a-reservation.md)
+ [取消容量预留](capacity-management-cancelling-a-capacity-reservation.md)
+ [删除容量预留](capacity-management-deleting-a-capacity-reservation.md)

# 编辑容量预留
<a name="capacity-management-editing-capacity-reservations"></a>

在创建容量预留后，您可以调整其 DPU 数并添加或移除其自定义标签。

**编辑容量预留**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 如果控制台导航窗格不可见，请选择左侧的扩展菜单。

1. 选择**管理**、**容量预留**。

1. 在容量预留列表中，执行以下操作之一：
   + 选择预留旁的按钮，然后选择**编辑**。
   + 选择预留链接，然后选择**编辑**。

1. 对于 **DPU**，选择或输入所需的数据处理器数。有关更多信息，请参阅 [了解 DPU](capacity-management.md#capacity-management-understanding-dpus)。
**注意**  
您可以随时申请向现有容量预留添加 DPU。
在预留变为活动预留 1 分钟后或上次添加 DPU 时，您可以请求从活动容量预留中减少 DPU。
当您请求减少 DPU 时，Athena 会优先移除空闲 DPU，而不是移除活动 DPU。如果查询正在消耗标记为要移除的 DPU，Athena 会等待查询完成，然后再移除 DPU。

1. （可选）对于**标签**，选择**移除**移除标签，或选择**添加新标签**添加新标签。

1. 选择**提交**。预留的详细信息页面将显示更新后的配置。

# 向预留添加工作组
<a name="capacity-management-adding-workgroups-to-a-reservation"></a>

在创建容量预留后，最多可以向预留添加 20 个工作组。向预留添加工作组即会告知 Athena 应对预留容量执行的查询。来自与预留无关的工作组的查询将继续使用默认的每 TB 扫描定价模型运行。

当预留具有两个或多个工作组时，来自这些工作组的查询可以使用预留容量。您可以随时添加和移除工作组。在添加或移除工作组时，正在运行的查询不会中断。

当您的预留处于待处理状态时，来自您添加的工作组的查询将继续使用默认每 TB 扫描定价模型运行，直到预留变为活动状态为止。

**向容量预留添加一个或多个工作组**

1. 在容量预留的详细信息页面中，选择**添加工作组**。

1. 在**添加工作组**页面中，选择要添加的工作组，然后选择**添加工作组**。无法将一个或多个工作组分配给预留。

   容量预留的详细信息页面列出了已添加的工作组。在这些工作组中运行的查询将在预留处于活动状态时使用预留的容量。

# 从预留中移除工作组
<a name="capacity-management-removing-a-workgroup-from-a-reservation"></a>

如果您不再需要工作组的专用容量或想要将工作组移至其自己的预留，则可以随时移除该工作组。将工作组从预留中移除这一过程很简单。在从预留中移除工作组后，已移除工作组中的查询恢复使用按需容量，并根据扫描的太字节（TB）进行计费。

**移除预留中的一个或多个工作组**

1. 在容量预留的详细信息页面中，选择要移除的工作组。

1. 选择**移除工作组**。**是否移除工作组？**提示会通知您在将工作组从预留中移除之前将完成所有当前处于活动状态的查询。

1. 选择**移除 **。容量预留的详细信息页面将不再显示已移除工作组。

# 取消容量预留
<a name="capacity-management-cancelling-a-capacity-reservation"></a>

如果您不再需要容量预留，则可以将其取消。允许正在使用预留的工作组中仍在运行的查询完成，但工作组中的其他查询将不再使用该预留。

**注意**  
无法保证已取消容量在未来可以重新预留。容量无法转移到另一个预留 AWS 账户 或 AWS 区域。

**取消容量预留**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 如果控制台导航窗格不可见，请选择左侧的扩展菜单。

1. 选择**管理**、**容量预留**。

1. 在容量预留列表中，执行以下操作之一：
   + 选择预留旁的按钮，然后选择**取消**。
   + 选择预留链接，然后选择**创建容量预留**。

1. 在**是否取消容量预订？**提示，输入**取消**，然后选择**取消容量预留**。

   预订状态将更改为**正在取消**，并显示一个进度横幅，通知您正在进行取消。

   在取消完成后，容量预留仍存在，但其状态显示为**已取消**。将在取消 45 天后删除该预留。在 45 天内，您不能重新利用或重复使用已取消预留，但是可以引用其标签并查看该预留以供历史参考。

# 删除容量预留
<a name="capacity-management-deleting-a-capacity-reservation"></a>

如果要移除所有对已取消容量预留的引用，可以删除该预留。必须取消预留，然后才能将其删除。已删除预留将立即从您的账户中移除，且无法再进行引用，包括其 ARN。

**删除容量预留**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 如果控制台导航窗格不可见，请选择左侧的扩展菜单。

1. 选择**管理**、**容量预留**。

1. 在容量预留列表中，执行以下操作之一：
   + 选择已取消预留旁的按钮，然后选择**操作**、**删除**。
   + 选择预留链接，然后选择**删除**。

1. 在**是否删除容量预留？**提示时，选择**删除**。

   将显示一个横幅，通知您容量预留已成功删除。已删除预留将不再出现在容量预留列表中。

# 容量预留的 IAM policy
<a name="capacity-reservations-iam-policy"></a>

要控制对容量预留的访问，使用资源级 IAM 权限或基于身份的 IAM policy。每当您使用 IAM 策略时，请确保遵循 IAM 最佳实践。有关更多信息，请参阅《*IAM 用户指南*》中的 [IAM 安全最佳实践](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)。

以下是 Athena 的特定过程。

有关 IAM 的特定信息，请参阅本节末尾列出的链接。有关示例 JSON 容量预留策略的信息，请参阅 [容量预留策略示例](example-policies-capacity-reservations.md)。

**在 IAM 控制台中使用可视化编辑器创建容量预留策略**

1. 登录 AWS 管理控制台，然后通过以下网址打开 IAM 控制台：[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 在左侧的导航窗格中，选择 **Policies (策略)**，然后选择 **Create policy (创建策略)**。

1. 在**可视化编辑器**选项卡上，选择**选择服务**。然后，选择要添加到策略的 Athena。

1. 选择 **Select actions (选择操作)**，然后选择要添加到策略的操作。可视化编辑器会显示 Athena 中可用的操作。有关更多信息，请参阅《服务授权参考》**中的 [Amazon Athena 的操作、资源和条件键](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonathena.html)。

1. 选择**添加操作**输入特定操作，或使用通配符（\$1）指定多个操作。

   预设情况下，您创建的策略允许执行选择的操作。如果您在 Athena 中选择对 `capacity-reservation` 资源执行一个或多个支持资源级权限的操作，则编辑器会列出 `capacity-reservation` 资源。

1. 选择**资源**指定特定于您的策略的容量预留。有关示例 JSON 容量预留策略的信息，请参阅 [容量预留策略示例](example-policies-capacity-reservations.md)。

1. 指定 `capacity-reservation` 资源，如下所示：

   ```
   arn:aws:athena:<region>:<user-account>:capacity-reservation/<capacity-reservation-name>
   ```

1. 选择 **Review policy (查看策略)**，然后为您创建的策略键入 **Name (名称)** 和 **Description (描述)**（可选）。查看策略摘要以确保您已授予所需的权限。

1. 选择**创建策略**可保存您的新策略。

1. 将此基于身份的策略附加到用户、组或角色。

有关详细信息，请参阅*服务授权参考*和《*IAM 用户指南*》中的以下主题：
+  [Amazon Athena 的操作、资源和条件键](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonathena.html) 
+  [使用可视化编辑器创建策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html#access_policies_create-visual-editor) 
+  [添加和移除 IAM 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) 
+  [控制对资源的访问](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_controlling.html#access_controlling-resources) 

有关示例 JSON 容量预留策略的信息，请参阅 [容量预留策略示例](example-policies-capacity-reservations.md)。

有关 Amazon Athena 操作的完整列表，请参阅 [Amazon Athena API 参考](https://docs.aws.amazon.com/athena/latest/APIReference/)中的 API 操作名称。

# 容量预留策略示例
<a name="example-policies-capacity-reservations"></a>

本节包含可用于启用对容量预留执行的各种操作的策略示例。每当您使用 IAM 策略时，请确保遵循 IAM 最佳实践。有关更多信息，请参阅《[IAM 用户指南](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)》中的 *IAM 安全最佳实践*。

容量预留是由 Athena 托管的 IAM 资源。因此，如果容量预留策略使用将 `capacity-reservation` 用作输入的操作，则必须指定容量预留 ARN，如下所示：

```
"Resource": [arn:aws:athena:<region>:<user-account>:capacity-reservation/<capacity-reservation-name>]
```

其中，`<capacity-reservation-name>` 为容量预留的名称。例如，对于名为 `test_capacity_reservation` 的容量预留，将其指定为资源，如下所示：

```
"Resource": ["arn:aws:athena:us-east-1:123456789012:capacity-reservation/test_capacity_reservation"]
```

有关 Amazon Athena 操作的完整列表，请参阅 [Amazon Athena API 参考](https://docs.aws.amazon.com/athena/latest/APIReference/)中的 API 操作名称。有关 IAM 策略的更多信息，请参阅《IAM 用户指南》**中的[使用可视化编辑器创建策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html#access_policies_create-visual-editor)。

**Example 用于列出容量预留的策略示例**  
以下策略允许所有用户列出所有容量预留。    
****  

```
{ 
    "Version":"2012-10-17",		 	 	  
    "Statement": [ 
        { 
            "Effect": "Allow", 
            "Action": [ 
                "athena:ListCapacityReservations" 
            ], 
            "Resource": "*" 
        } 
    ] 
}
```

**Example 适用于管理操作的策略示例**  
以下策略允许用户创建、取消和更新容量预留 `test_capacity_reservation` 以及获取其详细信息。该策略还允许用户将 `workgroupA` 和 `workgroupB` 分配给 `test_capacity_reservation`。    
****  

```
{ 
   "Version":"2012-10-17",		 	 	  
   "Statement":[ 
      { 
         "Effect": "Allow", 
         "Action": [ 
             "athena:CreateCapacityReservation", 
             "athena:GetCapacityReservation", 
             "athena:CancelCapacityReservation", 
             "athena:UpdateCapacityReservation", 
             "athena:GetCapacityAssignmentConfiguration", 
             "athena:PutCapacityAssignmentConfiguration" 
         ], 
         "Resource": [ 
             "arn:aws:athena:us-east-1:123456789012:capacity-reservation/test_capacity_reservation", 
             "arn:aws:athena:us-east-1:123456789012:workgroup/workgroupA", 
             "arn:aws:athena:us-east-1:123456789012:workgroup/workgroupB" 
         ] 
      } 
   ] 
}
```

# Athena 容量预留 API
<a name="capacity-management-api-list"></a>

以下列表包含指向 Athena 容量预留 API 操作的参考链接。有关数据结构及其他 Athena API 操作，请参阅 [https://docs.aws.amazon.com/athena/latest/APIReference/](https://docs.aws.amazon.com/athena/latest/APIReference/)（Amazon Athena API 参考）。
+  [CancelCapacityReservation](https://docs.aws.amazon.com/athena/latest/APIReference/API_CancelCapacityReservation.html) 
+  [CreateCapacityReservation](https://docs.aws.amazon.com/athena/latest/APIReference/API_CreateCapacityReservation.html) 
+  [DeleteCapacityReservation](https://docs.aws.amazon.com/athena/latest/APIReference/API_DeleteCapacityReservation.html) 
+  [GetCapacityAssignmentConfiguration](https://docs.aws.amazon.com/athena/latest/APIReference/API_GetCapacityAssignmentConfiguration.html) 
+  [GetCapacityReservation](https://docs.aws.amazon.com/athena/latest/APIReference/API_GetCapacityReservation.html) 
+  [ListCapacityReservations](https://docs.aws.amazon.com/athena/latest/APIReference/API_ListCapacityReservations.html) 
+  [PutCapacityAssignmentConfiguration](https://docs.aws.amazon.com/athena/latest/APIReference/API_PutCapacityAssignmentConfiguration.html) 
+  [UpdateCapacityReservation](https://docs.aws.amazon.com/athena/latest/APIReference/API_UpdateCapacityReservation.html) 

# 优化 Athena 性能
<a name="performance-tuning"></a>

本主题提供了有关提高 Athena 查询性能的一般信息和具体建议，以及如何解决与限制和资源使用情况相关的错误。

从广义上讲，优化可以分组为服务、查询和数据结构类别。在服务级别、如何编写查询以及如何构建数据和表格结构的决策都可能影响性能。

**Topics**
+ [优化服务使用](performance-tuning-service-level-considerations.md)
+ [优化查询](performance-tuning-query-optimization-techniques.md)
+ [优化数据](performance-tuning-data-optimization-techniques.md)
+ [使用列式存储格式](columnar-storage.md)
+ [使用分区和分桶](ctas-partitioning-and-bucketing.md)
+ [对您的数据进行分区](partitions.md)
+ [将分区投影与 Amazon Athena 结合使用](partition-projection.md)
+ [防止 Amazon S3 节流](performance-tuning-s3-throttling.md)
+ [其他资源](performance-tuning-additional-resources.md)

# 优化服务使用
<a name="performance-tuning-service-level-considerations"></a>

服务级别考虑因素包括每个账户运行的工作负载数量、不仅是 Athena 的服务配额，还包括跨服务的服务配额，以及考虑如何减少“资源不足”错误。

**Topics**
+ [在同一账户内运行多个工作负载](#performance-tuning-service-quotas)
+ [减少“资源不足”错误](#performance-tuning-resource-limits)

## 在同一账户内运行多个工作负载
<a name="performance-tuning-service-quotas"></a>

Athena 使用配额来限制账户级别的查询并发和 API 请求速率。超过这些配额可能会导致查询在执行期间或提交时失败。有关限额的更多信息，请参阅 [服务配额](service-limits.md)。

如果您在同一个 AWS 账户内运行多个工作负载，则您的工作负载会争用同一账户级配额。例如，当某个工作负载遇到意外突增的查询时，在同一账户中运行的其他工作负载可能会出现排队时间延长的现象，最坏情况下可能会因节流而导致查询提交失败。

我们建议您使用 CloudWatch 通过图表和控制面板监控服务使用情况。您还可以配置 CloudWatch 警报，在使用量接近并发查询的服务配额时提醒您，这样您就可以在达到配额限制之前采取措施。有关更多信息，请参阅 [使用 CloudWatch 监控 Athena 使用情况指标](monitoring-athena-usage-metrics.md)。

要控制查询并发并隔离账户内的工作负载，请使用容量预留。容量预留可在单个账户中提供专用的查询处理能力。容量以数据处理单元（DPU）为计量单位，可以进行增减以分别增加或减少查询并发。容量预留可以通过将容量分配给一个或多个工作组，将账户内的工作负载彼此隔离。有关更多信息，请参阅 [管理查询处理容量](capacity-management.md)。

尽管我们建议在不同的 AWS 账户中隔离不相关的工作负载（例如将开发与生产环境隔离），但这种方法不能通过提供可扩展的方式来提高查询并发性能。相反，使用容量预留可在单个账户中管理和扩展您的查询处理需求。

### 考虑其他服务的限额
<a name="performance-tuning-quotas-in-other-services"></a>

当 Athena 运行查询时，它可以调用其他强制实施限额的服务。在查询执行期间，Athena 可以对 AWS Glue Data Catalog、Amazon S3 以及其他 AWS 服务（如 IAM 和 AWS KMS）进行 API 调用。如果您使用[联合查询](federated-queries.md)，Athena 也会调用 AWS Lambda。所有这些服务都有自己的限制和限额，可以超出。当查询执行遇到来自这些服务的错误时，查询会失败并包括来自源服务的错误。系统会重试可恢复的错误；但如果问题不能及时解决，查询仍可能失败。请务必仔细阅读错误消息，以确定它们是来自 Athena 还是来自其他服务。此性能优化部分介绍了一些相关错误。

有关如何解决由 Amazon S3 服务限额导致的错误的更多信息，请参阅本文档后面的 [避免文件过多](performance-tuning-data-optimization-techniques.md#performance-tuning-avoid-having-too-many-files)。有关 Amazon S3 性能优化的更多信息，请参阅《*Amazon S3 用户指南*》中的[最佳实践设计模式：优化 Amazon S3 性能](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html)。

## 减少“资源不足”错误
<a name="performance-tuning-resource-limits"></a>

Athena 在分布式查询引擎中运行查询。当您提交查询时，Athena 引擎查询计划程序会估计运行查询所需的计算容量，并相应地准备计算节点集群。有些查询（例如 DDL 查询）只能在一个节点上运行。对大型数据集的复杂查询在更大的集群上运行。节点是统一的，具有相同的内存、CPU 和磁盘配置。Athena 横向扩展，而非纵向扩展，以处理要求更高的查询。

有时，查询的需求会超过运行查询的集群可用的资源。发生这种情况时，查询会失败，并显示错误查询在此缩放系数耗尽了资源。

最常耗尽的资源是内存，但在极少数情况下，也可能是磁盘空间。内存错误通常发生在引擎执行联接或窗口函数时，但也可能发生在不同的计数和聚合中。

即使查询因出现“资源不足”错误而失败一次，当您再次运行它时，它也可能会成功。查询执行的确定性不定。加载数据需要多长时间以及中间数据集在节点上的分布方式等因素可能会导致不同的资源使用情况。例如，假设一个查询连接两个表，并且在连接条件的值分布中存在严重偏差。这样的查询在大多数情况下都可以成功，但是当最常见的值最终由同一个节点处理时，偶尔会失败。

为防止您的查询超出可用资源，请使用本文档中提到的性能调整提示。特别是，有关如何优化耗尽可用资源的查询的提示，请参阅 [优化联接](performance-tuning-query-optimization-techniques.md#performance-tuning-optimizing-joins)、[缩小窗口函数的范围，或者将其移除](performance-tuning-query-optimization-techniques.md#performance-tuning-optimizing-window-functions) 和 [使用近似值优化查询](performance-tuning-query-optimization-techniques.md#performance-tuning-optimizing-queries-by-using-approximations)。

# 优化查询
<a name="performance-tuning-query-optimization-techniques"></a>

使用本节中介绍的查询优化技巧来加快查询的运行速度，或者将其作为超出 Athena 资源限制的查询的变通方法。

## 优化联接
<a name="performance-tuning-optimizing-joins"></a>

在分布式查询引擎中执行联接有许多不同的策略。其中最常见的两种是分布式哈希联接和具有复杂联接条件的查询。

### 在分布式哈希联接中，将大型表放在左边，小型表放在右边
<a name="performance-tuning-distributed-hash-join"></a>

最常见的连接类型使用等式比较作为连接条件。Athena 以分布式哈希联接的形式运行这种联接。

在分布式哈希联接中，引擎从联接的一端构建查找表（哈希表）。该端称为*构建端*。构建端的记录分布在各个节点上。每个节点都为其子集生成一个查找表。然后，联接的另一端（称为*探测端*）通过节点进行流式传输。探测端的记录以与构建端相同的方式分布在节点上。这使每个节点都能够通过在自己的查找表中查找匹配的记录来执行联接。

当从联接的构建端创建的查找表无法存入内存时，查询会失败。即使构建端的总大小小于可用内存，如果记录的分布存在明显偏差，查询也会失败。在极端情况下，所有记录的联接条件值可能相同，并且必须放入单个节点上的内存中。如果将一组值发送到同一个节点，并且这些值加起来超过可用内存，则即使是偏差较小的查询也会失败。节点确实能够将记录溢出到磁盘，但是溢出会减慢查询的执行速度，可能不足以防止查询失败。

Athena 尝试重新排序联接，使用较大的关系作为探测端，将较小的关系用作构建端。但是，由于 Athena 不管理表中的数据，因此它的信息有限，通常必须假设第一个表更大，第二个表更小。

使用基于等式的联接条件编写联接时，假设 `JOIN` 关键字左侧的表是探测端，右侧的表是构建端。确保右侧的表（即构建端）是表格中较小的一个。如果无法将联接的构建端缩小到足以放入内存，请考虑运行多个查询来联接构建表的子集。

### 使用 EXPLAIN 分析具有复杂联接的查询
<a name="performance-tuning-other-join-types"></a>

具有复杂联接条件的查询（例如，使用 `LIKE`、`>` 或其他运算符的查询）通常对计算要求很高。在最糟糕的情况下，必须将联接一侧的每条记录与联接另一侧的每条记录进行比较。由于执行时间随记录数的平方而增长，因此此类查询有可能超过最大执行时间。

要提前了解 Athena 将如何执行您的查询，您可以使用 `EXPLAIN` 语句。有关更多信息，请参阅[在 Athena 中使用 EXPLAIN 和 EXPLAIN ANALYZE](athena-explain-statement.md)和[了解 Athena EXPLAIN 语句结果](athena-explain-statement-understanding.md)。

## 缩小窗口函数的范围，或者将其移除
<a name="performance-tuning-optimizing-window-functions"></a>

由于窗口函数是资源密集型操作，因此它们可能会使查询运行缓慢甚至失败，并显示消息查询在此缩放系数耗尽了资源。窗口函数将它们操作的所有记录保存在内存中，以便计算其结果。当窗口非常大时，窗口函数可能会耗尽内存。

要确保查询在可用内存限制内运行，请减小窗口函数操作的窗口的大小。为此，您可以添加 `PARTITIONED BY` 子句或缩小现有分区子句的范围。

### 使用非窗口函数
<a name="performance-tuning-optimizing-window-functions-rewrite"></a>

有时，使用窗口函数的查询可以在没有窗口函数的情况下重写。例如，您可以使用 `ORDER BY` 和 `LIMIT`，而不是使用 `row_number` 来查找前 `N` 条记录。您可以使用 [max\$1by](https://trino.io/docs/current/functions/aggregate.html#max_by)、[min\$1by](https://trino.io/docs/current/functions/aggregate.html#min_by) 和[任意](https://trino.io/docs/current/functions/aggregate.html#arbitrary)聚合函数，而不是使用 `row_number` 或 `rank` 删除重复记录。

例如，假设您有一个包含来自传感器的更新的数据集。传感器会定期报告其电池状态，并包含一些元数据（例如位置）。如果您想知道每个传感器的上次电池状态及其位置，可以使用以下查询：

```
SELECT sensor_id,
       arbitrary(location) AS location,
       max_by(battery_status, updated_at) AS battery_status
FROM sensor_readings
GROUP BY sensor_id
```

由于每条记录的位置等元数据都相同，因此您可以使用 `arbitrary` 函数从组中选取任何值。

要获取最后电池状态，您可以使用 `max_by` 函数。`max_by` 函数从发现另一列的最大值的记录中选取一列的值。在这种情况下，它将返回记录的电池状态以及组内最后一次更新时间。与使用窗口函数的等效查询相比，此查询运行速度更快，占用的内存也更少。

## 优化聚合
<a name="performance-tuning-optimizing-aggregations"></a>

当 Athena 执行聚合时，它会使用 `GROUP BY` 子句中的列在工作节点之间分配记录。为了尽可能高效地将记录与组进行匹配，节点会尝试将记录保存在内存中，但必要时会将其溢出到磁盘。

避免在 `GROUP BY` 子句中包含多余的列也是个不错的做法。由于较少的列需要更少的内存，因此使用较少的列描述组的查询效率更高。数字列使用的内存也比字符串少。例如，当您聚合同时具有数字类别 ID 和类别名称的数据集时，在 `GROUP BY` 子句中仅使用类别 ID 列。

有时，查询会在 `GROUP BY` 子句中包含列，以避免列必须是 `GROUP BY` 子句的一部分或是聚合表达式。如果不遵守此规则，您可能会收到如下错误消息：

 EXPRESSION\$1NOT\$1AGGREGATE：第 1:8 行：'category' 必须是聚合表达式或出现在 GROUP BY 子句中 

为避免在 `GROUP BY` 子句中添加冗余列，可以使用[任意](https://trino.io/docs/current/functions/aggregate.html#arbitrary)函数，如下例所示。

```
SELECT country_id,
       arbitrary(country_name) AS country_name,
       COUNT(*) AS city_count
FROM world_cities
GROUP BY country_id
```

`ARBITRARY` 函数从组中返回任意值。当您知道组中所有记录的某列值相同，但该值不能标识该组时，该函数很有用。

## 优化前 N 个查询
<a name="performance-tuning-optimizing-top-n-queries"></a>

`ORDER BY` 子句按排序顺序返回查询结果。Athena 使用分布式排序在多个节点上并行运行排序操作。

如果您不严格要求对结果进行排序，请避免添加 `ORDER BY` 子句。此外，如果不是严格必需的，请避免将 `ORDER BY` 添加到内部查询中。在许多情况下，查询计划程序可以删除冗余排序，但这并不能保证。此规则的一个例外情况是，如果内部查询正在执行前 `N` 个操作，例如查找 `N` 个最新或 `N` 个最常见的值。

当 Athena 看到 `LIMIT` 与 `ORDER BY` 一起使用时，它会知道您正在运行前 `N` 个查询，因此会相应地使用专用操作。

**注意**  
尽管 Athena 也可以经常使用前 `N` 个来检测 `row_number` 等窗口函数，但我们建议使用 `ORDER BY` 和 `LIMIT` 的简单版本。有关更多信息，请参阅 [缩小窗口函数的范围，或者将其移除](#performance-tuning-optimizing-window-functions)。

## 仅包含必需列
<a name="performance-tuning-include-only-required-columns"></a>

如果您并不严格需要某一列，请不要将其包含在查询中。查询需要处理的数据越少，运行速度就越快。这样既可以减少所需的内存量，也减少了必须在节点之间发送的数据量。如果您使用的是列式文件格式，则减少列数也会减少从 Amazon S3 读取的数据量。

Athena 对结果中的列数没有具体限制，但是查询的执行方式限制了可能的列组合大小。列的组合大小包括其名称和类型。

例如，以下错误是由超出关系描述符大小限制的关系引起的：

 GENERIC\$1INTERNAL\$1ERROR: io.airlift.bytecode.CompilationException 

要解决此问题，请减少查询中的列数，或创建子查询并使用可降低检索数据量的 `JOIN`。如果您的查询在最外层的查询中执行 `SELECT *`，则应将 `*` 更改为仅包含所需列的列表。

## 使用近似值优化查询
<a name="performance-tuning-optimizing-queries-by-using-approximations"></a>

Athena 支持[近似聚合函数](https://trino.io/docs/current/functions/aggregate.html#appro)，用于计算不同值、最常见的值、百分位数（包括近似中位数）和创建直方图。当不需要精确值时，请使用这些函数。

与 `COUNT(DISTINCT col)` 操作不同，[approx\$1distinct](https://trino.io/docs/current/functions/aggregate.html#approx_distinct) 使用的内存要少得多，运行速度更快。同样，使用 [numeric\$1histogram](https://trino.io/docs/current/functions/aggregate.html#numeric_histogram) 代替[直方图](https://trino.io/docs/current/functions/aggregate.html#histogram)会使用近似法，因此内存更少。

## 优化 LIKE
<a name="performance-tuning-optimizing-like"></a>

您可以使用 `LIKE` 来查找匹配的字符串，但是对于长字符串，这将占用大量计算资源。在大多数情况下，[regexp\$1like](https://trino.io/docs/current/functions/regexp.html#regexp_like) 函数是一种更快的替代方案，而且还提供了更大的灵活性。

通常，您可以通过锚定要查找的子字符串来优化搜索。例如，如果您正在寻找前缀，最好使用 '*substr*%' 而不是 '%*substr*%'。或者，如果您使用的是 `regexp_like`，请使用 '^*substr*'。

## 使用 UNION ALL 代替 UNION
<a name="performance-tuning-use-union-all-instead-of-union"></a>

 `UNION ALL` 和 `UNION` 还有两种方法可以将两个查询的结果合并为一个结果。`UNION ALL` 将第一个查询的记录与第二个查询的记录连接起来，`UNION` 执行相同的操作，同时也会删除重复的记录。`UNION` 需要处理所有记录并找到重复项，这需要占用大量内存和计算，但 `UNION ALL` 操作速度相对较快。除非需要对记录进行重复数据删除，否则请使用 `UNION ALL` 以获得最佳性能。

## 对大型结果集使用 UNLOAD
<a name="performance-tuning-use-unload-for-large-result-sets"></a>

当查询的结果预计会很大（例如，成千上万行或更多）时，请使用 UNLOAD 导出结果。在大多数情况下，这比运行常规查询要快，而且使用 `UNLOAD` 还可以让您更好地控制输出。

查询执行完毕后，Athena 会将结果作为单个未压缩的 CSV 文件存储在 Amazon S3 上。这需要比 `UNLOAD` 更长的时间，这不仅是因为结果未压缩，还因为操作无法并行化。相比之下，`UNLOAD` 直接从 Worker 节点写入结果，并充分利用计算集群的并行度。此外，您可以配置 `UNLOAD` 为以压缩格式和其他文件格式（例如 JSON 和 Parquet）写入结果。

有关更多信息，请参阅 [UNLOAD](unload.md)。

## 使用 CTAS 或 Glue ETL 来具体化常用的聚合
<a name="performance-tuning-use-ctas-or-glue-etl-to-materialize-frequently-used-aggregations"></a>

‘Materializing' 查询是一种通过存储预先计算的复杂查询结果（例如聚合和联接），以便在后续查询中重复使用，从而提高查询性能的方法。

如果您的许多查询包含相同的联接和聚合，则可以将常见子查询具体化为新表，然后对该表运行查询。您可以使用 [从查询结果创建表（CTAS）](ctas.md) 或专用 ETL 工具（如 [Glue ETL](https://aws.amazon.com/glue)）创建新表。

例如，假设您有一个控制面板，其中包含显示订单数据集不同方面的小部件。每个小部件都有自己的查询，但所有查询都共享相同的联接和筛选器。订单表与订单项目表联接，并且有一个筛选器仅显示最近三个月。如果您确定了这些查询的常用功能，则可以创建小部件可以使用的新表。这样可以减少重复并提高性能。缺点是必须使新表保持最新状态。

## 重复使用查询结果
<a name="performance-tuning-reuse-query-results"></a>

同一个查询通常会在短时间内多次运行。例如，当多人打开同一个数据控制面板时，可能会发生这种情况。运行查询时，您可以让 Athena 重复使用之前计算的结果。您可以指定要重复使用的结果的最大期限。如果之前在该时间范围内运行过相同的查询，Athena 将返回这些结果，而不会再次运行查询。有关更多信息，请参阅《*Amazon Athena 用户指南*》中的 [在 Athena 中重复使用查询结果](reusing-query-results.md)，以及 *AWS 大数据博客*中的[通过 Amazon Athena 查询结果重复使用来降低成本并提高查询性能](https://aws.amazon.com/blogs/big-data/reduce-cost-and-improve-query-performance-with-amazon-athena-query-result-reuse/)。

# 优化数据
<a name="performance-tuning-data-optimization-techniques"></a>

性能不仅取决于查询，还取决于数据集的组织方式及其使用的文件格式和压缩。

## 对您的数据进行分区
<a name="performance-tuning-partition-your-data"></a>

分区可将您的表格分成多个部分，并根据日期、国家或地区等属性将相关数据保存在一起。分区键充当虚拟列。您可以在创建表时定义分区键，并使用它们来筛选查询。对分区键列进行筛选时，只读取来自匹配分区的数据。例如，如果您的数据集按日期分区，并且您的查询的筛选条件仅与上周匹配，则只读取上周的数据。有关分区的更多信息，请参阅 [对您的数据进行分区](partitions.md)。

## 选择支持您的查询的分区键
<a name="performance-tuning-pick-partition-keys-that-will-support-your-queries"></a>

由于分区会对查询性能产生重大影响，因此在设计数据集和表时，请务必考虑如何谨慎分区。分区键过多会导致数据集碎片化，文件过多或过小。相反，分区键太少或根本没有分区会导致查询扫描的数据超出必要的范围。

### 避免针对罕见的查询进行优化
<a name="performance-tuning-avoid-optimizing-for-rare-queries"></a>

一个好的策略是针对最常见的查询进行优化，避免针对罕见的查询进行优化。例如，如果您的查询以天为单位的时间跨度，即使某些查询筛选到该级别，也不要按小时进行分区。如果您的数据具有精细的时间戳列，则按小时筛选的罕见查询可以使用时间戳列。即使罕见案例扫描的数据比必要的要多一点，但为了极少数情况而降低整体性能通常也不是一个很好的权衡方案。

要减少查询必须扫描的数据量，从而提高性能，请使用列式文件格式并对记录进行排序。与其按小时分区，不如按时间戳对记录进行排序。对于时间范围较短的查询，按时间戳排序几乎与按小时分区一样有效。此外，按时间戳排序通常不会损害以天为单位的时间窗口的查询性能。有关更多信息，请参阅 [使用列式文件格式](#performance-tuning-use-columnar-file-formats)。

请注意，如果所有分区键上都有谓词，则对包含数万个分区的表进行查询的性能会更好。这是为最常见的查询设计分区方案的另一个原因。有关更多信息，请参阅 [按等式查询分区](#performance-tuning-query-partitions-by-equality)。

## 使用分区投影
<a name="performance-tuning-use-partition-projection"></a>

分区投影是 Athena 的一项功能，它不是将分区信息存储在 AWS Glue Data Catalog 中，而是作为规则存储在 AWS Glue 中表的属性中。当 Athena 计划对配置了分区投影的表进行查询时，它会读取该表的分区投影规则。Athena 根据查询和规则计算要在内存中读取的分区，而不是在 AWS Glue Data Catalog 中查找分区。

除了简化分区管理外，分区投影还可以提高具有大量分区的数据集的性能。当查询包含范围而不是分区键的特定值时，分区越多，在目录中查找匹配的分区所需的时间就越长。使用分区投影，无需进入目录即可在内存中计算筛选器，而且速度可以快得多。

在某些情况下，分区投影可能会导致性能降低。例如，当表为“稀疏表”时。稀疏表不包含分区投影配置所描述的分区键值的每个排列的数据。对于稀疏表，通过查询计算得出的分区集和分区投影配置都会在 Amazon S3 上列出，即使它们没有数据。

使用分区投影时，请确保在所有分区键上都包含谓词。缩小可能值的范围，以避免不必要的 Amazon S3 列表。假设一个分区键的范围为一百万个值，而一个查询对该分区键没有任何筛选器。要运行查询，Athena 必须执行至少一百万个 Amazon S3 列表操作。无论您是使用分区投影还是在目录中存储分区信息，查询特定值时查询速度最快。有关更多信息，请参阅 [按等式查询分区](#performance-tuning-query-partitions-by-equality)。

在为分区投影配置表时，请确保您指定的范围合理。如果查询不包含分区键的谓词，则使用该键范围内的所有值。如果您的数据集是在特定日期创建的，请使用该日期作为任何日期范围的起点。使用 `NOW` 作为日期范围的结束日期。避免使用具有大量值的数值范围，并考虑改用[注入](partition-projection-dynamic-id-partitioning.md#partition-projection-injection)类型。

更多有关分区投影的信息，请参阅 [将分区投影与 Amazon Athena 结合使用](partition-projection.md)。

## 使用分区索引
<a name="performance-tuning-use-partition-indexes"></a>

分区索引是 AWS Glue Data Catalog 中的一项功能，它可以提高具有大量分区的表的分区查找性能。

目录中的分区列表就像关系数据库中的表。该表包含用于分区键的列，还有一列用于分区位置。查询分区表时，将通过扫描该表来查找分区位置。

与关系数据库一样，您可以通过添加索引来提高查询性能。您可以添加多个索引以支持不同的查询模式。AWS Glue Data Catalog 分区索引同时支持等式和比较运算符，例如 `>`、`>=` 和 `<`，并与 `AND` 运算符组合使用。有关更多信息，请参阅《AWS Glue 开发人员指南**》中的[在 AWS Glue 中使用分区索引](https://docs.aws.amazon.com/glue/latest/dg/partition-indexes.html)和 *AWS 大数据博客*中的[使用 AWS Glue Data Catalog 分区索引提高 Amazon Athena 查询性能](https://aws.amazon.com/blogs/big-data/improve-amazon-athena-query-performance-using-aws-glue-data-catalog-partition-indexes/)。

## 始终使用 STRING 作为分区键的类型
<a name="performance-tuning-always-use-string-as-the-type-for-partition-keys"></a>

在查询分区键时，请记住：Athena 要求分区键的类型必须为 `STRING` 类型才能下推分区筛选到 AWS Glue。如果分区数量不小，则使用其他类型可能会导致性能降低。如果您的分区键值类似于日期或类似数字，请在查询中将其转换为相应的类型。

## 删除旧的和空的分区
<a name="performance-tuning-remove-old-and-empty-partitions"></a>

如果您从 Amazon S3 上的分区中移除数据（例如，使用 Amazon S3 [生命周期](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html)），则还应从 AWS Glue Data Catalog 中删除该分区条目。在查询计划期间，与查询匹配的任何分区都会在 Amazon S3 上列出。如果您有许多空分区，则列出这些分区的开销可能会造成不利影响。

另外，如果您有成千上万个分区，可以考虑删除旧数据不再相关的分区元数据。例如，如果查询从不查看超过一年的数据，则可以定期删除旧分区的分区元数据。如果分区的数量增加到数万个，则移除未使用的分区可以加快所有分区键上都不包含谓词的查询速度。有关在查询中包含所有分区键的谓词的信息，请参阅 [按等式查询分区](#performance-tuning-query-partitions-by-equality)。

## 按等式查询分区
<a name="performance-tuning-query-partitions-by-equality"></a>

由于可以直接加载分区元数据，因此在所有分区键上包含等式谓词的查询运行得更快。避免查询中一个或多个分区键没有谓词，或者谓词选择一定范围的值。对于此类查询，必须筛选所有分区的列表以找到匹配的值。对于大多数表来说，开销很小，但是对于具有成千上万或更多分区的表，开销可能会变得很大。

如果无法重写查询以按等式筛选分区，则可以尝试分区投影。有关更多信息，请参阅 [使用分区投影](#performance-tuning-use-partition-projection)。

## 避免使用 MSCK REPAIR TABLE 进行分区维护
<a name="performance-tuning-avoid-using-msck-repair-table-for-partition-maintenance"></a>

由于 `MSCK REPAIR TABLE` 可能需要很长时间才能运行，只能添加新分区，而不会删除旧分区，因此这不是管理分区的有效方法（请参阅 [注意事项和限制](msck-repair-table.md#msck-repair-table-considerations)）。

使用 [AWS Glue Data Catalog API](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api-catalog.html)、[ALTER TABLE ADD PARTITION](alter-table-add-partition.md) 或 [AWS Glue 爬网程序](https://docs.aws.amazon.com/glue/latest/dg/crawler-running.html)以更好地手动管理分区。作为替代方案，您可以使用分区投影，这样就无需管理分区。有关更多信息，请参阅 [将分区投影与 Amazon Athena 结合使用](partition-projection.md)。

## 验证您的查询是否与分区方案兼容
<a name="performance-tuning-validate-that-your-queries-are-compatible-with-the-partitioning-scheme"></a>

您可以使用 [`EXPLAIN`](athena-explain-statement.md) 语句提前检查查询将扫描哪些分区。在查询前面加上 `EXPLAIN` 关键字，然后在 `EXPLAIN` 输出底部附近查找每个表的源片段（例如 `Fragment 2 [SOURCE]`）。查找右侧被定义为分区键的分配。下面的行包括运行查询时将扫描的该分区键的所有值的列表。

例如，假设您在表上有一个 `dt` 分区键的查询，并在查询前面加上 `EXPLAIN`。如果查询中的值是日期，并且筛选器选择了三天的范围，则 `EXPLAIN` 输出可能如下所示：

```
dt := dt:string:PARTITION_KEY
    :: [[2023-06-11], [2023-06-12], [2023-06-13]]
```

`EXPLAIN` 输出显示计划程序为该分区键找到了三个与查询相匹配的值。同时还会显示这些值是什么。有关使用 `EXPLAIN` 的更多信息，请参阅 [在 Athena 中使用 EXPLAIN 和 EXPLAIN ANALYZE](athena-explain-statement.md) 和 [了解 Athena EXPLAIN 语句结果](athena-explain-statement-understanding.md)。

## 使用列式文件格式
<a name="performance-tuning-use-columnar-file-formats"></a>

Parquet 和 ORC 等列式文件格式专为分布式分析工作负载而设计。它们按列而不是按行组织数据。以列式格式组织数据具有以下优点：
+ 仅加载查询所需的列
+ 减少了需要加载的总数据量
+ 列值存储在一起，因此可以有效地压缩数据 
+ 文件可以包含允许引擎跳过加载不需要的数据的元数据

举例说明如何使用文件元数据，文件元数据可以包含有关数据页面中最小值和最大值的信息。如果查询的值不在元数据中注明的范围内，则可以跳过该页面。

使用此元数据来提高性能的一种方法是确保对文件中的数据进行排序。例如，假设您有查询来查找短时间段内 `created_at` 条目所在的记录。如果您的数据按 `created_at` 列排序，Athena 可以使用文件元数据中的最小值和最大值来跳过数据文件中不需要的部分。

使用列式文件格式时，请确保文件不要太小。如 [避免文件过多](#performance-tuning-avoid-having-too-many-files) 中所述，包含许多小文件的数据集会导致性能问题。对于列式文件格式尤其如此。对于小文件，列式文件格式的开销大于好处。

请注意，Parquet 和 ORC 在内部按行组（Parquet）和条带（ORC）进行组织。行组的默认大小为 128MB，条带的默认大小为 64MB。如果您有许多列，则可以增加行组和条带大小以提高性能。不建议将行组或条带大小减小到其默认值以下。

要将其他数据格式转换为 Parquet 或 ORC，您可以使用 AWS Glue ETL 或 Athena。有关更多信息，请参阅 [转换为列式格式](columnar-storage.md#convert-to-columnar)。

## 压缩数据
<a name="performance-tuning-compress-data"></a>

Athena 支持多种压缩格式。查询压缩数据更快，也更便宜，因为您需要为解压缩前扫描的字节数付费。

[gzip](https://www.gnu.org/software/gzip/) 格式提供了良好的压缩比，并且在其他工具和服务中具有广泛的支持。[zstd](https://facebook.github.io/zstd/)（Zstandard）格式是一种较新的压缩格式，在性能和压缩比之间取得了很好的平衡。

压缩 JSON 和 CSV 数据等文本文件时，请尽量在文件数量和文件大小之间取得平衡。大多数压缩格式都要求读取器从一开始就读取文件。这意味着通常不能并行处理压缩的文本文件。在查询处理过程中，大型未压缩文件通常在工作线程之间拆分，以实现更高的并行度；但是对于大多数压缩格式来说，这是不可能的。

如 [避免文件过多](#performance-tuning-avoid-having-too-many-files) 中所述，文件最好不要太多也不要太少。由于文件数量是可以处理查询的工作线程数量的限制，因此对于压缩的文件尤其如此。

有关在 Athena 中使用压缩的更多信息，请参阅 [在 Athena 中使用压缩](compression-formats.md)。

## 使用存储桶查找具有高基数的键
<a name="performance-tuning-use-bucketing-for-lookups-on-keys-with-high-cardinality"></a>

存储桶是一种根据其中一列的值将记录分发到单独文件中的技术。这样可以确保所有具有相同值的记录都位于同一个文件中。当您的键具有高基数并且您的许多查询都查找该键的特定值时，存储桶很有用。

例如，假设您查询一组记录寻求特定用户。如果数据按用户 ID 划分存储桶，Athena 会事先知道哪些文件包含特定 ID 的记录，哪些文件没有。这使得 Athena 能够只读取可能包含该 ID 的文件，从而大大减少了读取的数据量。它还缩短了在数据中搜索特定 ID 所需的计算时间。

### 当查询经常在列中搜索多个值时，请避免分桶
<a name="performance-tuning-disadvantages-of-bucketing"></a>

当查询经常在存储数据的列中搜索多个值时，存储桶的价值就会降低。查询的值越多，必须读取所有或大多数文件的可能性就越大。例如，如果您有三个存储桶，并且查询查找三个不同的值，则可能必须读取所有文件。当查询查找单个值时，存储桶效果最好。

有关更多信息，请参阅 [使用分区和分桶](ctas-partitioning-and-bucketing.md)。

## 避免文件过多
<a name="performance-tuning-avoid-having-too-many-files"></a>

由许多小文件组成的数据集会导致整体查询性能不佳。当 Athena 计划查询时，它会列出所有分区位置，这需要时间。处理和请求每个文件也会产生计算开销。因此，从 Amazon S3 加载单个更大的文件要比从许多较小的文件加载相同记录要快。

在极端情况下，您可能会遇到 Amazon S3 服务限制。Amazon S3 每秒最多支持向单个索引分区发出 5500 个请求。最初，存储桶被视为单个索引分区，但是随着请求负载的增加，可以将其拆分为多个索引分区。

Amazon S3 着眼于请求模式，并根据键前缀进行拆分。如果您的数据集包含成千上万个文件，则来自 Athena 的请求可能会超过请求限额。即使文件较少，如果对同一个数据集进行多个并发查询，也可能超过限额。访问相同文件的其他应用程序可能会占请求总数。

超过请求速率 `limit` 时，Amazon S3 会返回以下错误。此错误包含在 Athena 中查询的状态信息中。

 减速：请降低请求速率 

要排除故障，首先要确定错误是由单个查询引起的，还是由读取相同文件的多个查询引起的。如果是后者，请协调查询的运行，这样它们就不会同时运行。为此，请在应用程序中添加排队机制甚至重试。

如果运行单个查询触发错误，请尝试合并数据文件或修改查询以减少读取的文件。合并小文件的最佳时机是在写入它们之前。为此，请考虑以下技术：
+ 将写入文件的过程更改为写入更大的文件。例如，可以在写入记录之前将其缓冲更长时间。
+ 将文件放在 Amazon S3 上的某个位置，然后使用像 Glue ETL 这样的工具将它们合并成更大的文件。然后，将较大的文件移动到表格所指向的位置。有关更多信息，请参阅《AWS Glue 开发人员指南**》中的[读取较大组中的输入文件](https://docs.aws.amazon.com/glue/latest/dg/grouping-input-files.html)和 *AWS re:Post 知识中心*中的[如何配置 AWS Glue ETL 任务以输出较大文件？](https://repost.aws/knowledge-center/glue-job-output-large-files)。
+ 减少分区键的数量。当分区键过多时，每个分区可能只有几个记录，从而导致小文件数量过多。有关决定创建哪些分区的信息，请参阅 [选择支持您的查询的分区键](#performance-tuning-pick-partition-keys-that-will-support-your-queries)。

## 避免在分区之外设置额外的存储层次结构
<a name="performance-tuning-avoid-additional-storage-hierarchies-beyond-the-partition"></a>

为避免查询计划开销，请在每个分区位置以扁平结构存储文件。请勿使用任何其他目录层次结构。

当 Athena 计划查询时，它会列出与该查询匹配的所有分区中的所有文件。尽管 Amazon S3 本身没有目录，但惯例是将 `/` 正斜杠解释为目录分隔符。当 Athena 列出分区位置时，它会递归列出找到的任何目录。当分区内的文件按层次结构组织时，会出现多轮列表。

当所有文件都直接位于分区位置时，大多数时候只需要执行一个列表操作。但是，如果分区中有超过 1000 个文件，则需要进行多次顺序列表操作，因为 Amazon S3 每次列表操作仅返回 1000 个对象。一个分区中有 1000 个以上的文件还会造成其他更严重的性能问题。有关更多信息，请参阅 [避免文件过多](#performance-tuning-avoid-having-too-many-files)。

## 仅在必要时使用 SymlinkTextInputFormat
<a name="performance-tuning-use-symlinktextinputformat-only-when-necessary"></a>

使用 [https://athena.guide/articles/stitching-tables-with-symlinktextinputformat](https://athena.guide/articles/stitching-tables-with-symlinktextinputformat) 技术可以解决表的文件没有整齐地组织到分区中的情况。例如，当所有文件都使用相同前缀或具有不同架构的文件位于同一位置时，符号链接可能很有用。

但是，使用符号链接会增加查询执行的间接级别。这些间接级别会影响整体性能。必须读取符号链接文件，并且必须列出它们定义的位置。这会增加到 Amazon S3 的多次往返行程，而通常的 Hive 表不需要这些往返行程。总之，只有在没有更好的选项（例如重组文件）时，才应使用 `SymlinkTextInputFormat`。

# 使用列式存储格式
<a name="columnar-storage"></a>

[Apache Parquet](https://parquet.apache.org) 和 [ORC](https://orc.apache.org/) 是针对快速检索数据进行了优化的列式存储格式，用于 AWS 分析应用程序中。

列式存储格式具有以下特征，使其适合用于 Athena：
+ *按列压缩，针对列数据类型选择压缩算法*，可以节省 Amazon S3 中的存储空间，并减少查询处理期间的磁盘空间和输入/输出。
+ Parquet and ORC 中的*谓词下推*使得 Athena 查询可以只提取所需的数据块，从而提高查询性能。当 Athena 查询从您的数据获取特定列值时，它使用来自数据块谓词的统计信息（例如最大/最小值）来确定读取还是跳过改数据块。
+ Parquet 和 ORC 中的*数据拆分*使得 Athena 可以将数据读取拆分为多个读进程，在查询处理期间增加并行度。

要将现有原始数据从其他存储格式转换为 Parquet 或 ORC，您可以在 Athena 中运行 [CREATE TABLE AS SELECT (CATS)](ctas.md)查询，并将数据存储格式指定为 Parquet 或 ORC，或使用 AWS Glue 爬网程序。

## 在 Parquet 和 ORC 之间进行选择
<a name="columnar-storage-choosing"></a>

将根据具体的使用需求在 ORC（优化的行列式）和 Parquet 之间进行选择。

Apache Parquet 可实现高效的数据压缩和编码方案，非常适合运行复杂的查询和处理大量数据。Parquet 已针对与 [Apache Arrow](https://arrow.apache.org/) 配合使用进行了优化，如果使用的工具与 Arrow 相关，这可能会很有优势。

可通过 ORC 提高效存储 Hive 数据。ORC 文件通常比 Parquet 文件小，ORC 索引可以加快查询速度。此外，ORC 还支持结构、映射和列表等复杂类型。

在 Parquet 和 ORC 之间进行选择时，请注意以下事项：

**查询性能** - 由于 Parquet 支持更广泛的查询类型，如果您打算执行复杂查询，建议选择 Parquet。

**复杂数据类型** - 如果您使用的是复杂数据类型，建议选择 ORC，因为它支持更广泛的复杂数据类型。

**文件大小** - 如果需要考虑磁盘空间，ORC 生成的文件通常较小，可以降低存储成本。

**压缩** - Parquet 和 ORC 都可实现优质压缩效果，但最适合您的格式可能取决于您的具体使用案例。

**发展** - Parquet 和 ORC 都支持架构发展，这意味着您可以随着时间的推移添加、移除或修改列。

Parquet 和 ORC 都适用于大数据应用程序，但是还是要根据场景需求进行选择。您可能需要对数据和查询进行基准测试，才能了解哪种格式更适合您的使用案例。

## 转换为列式格式
<a name="convert-to-columnar"></a>

将 JSON 或 CSV 等源数据轻松转换为列式格式的选项包括使用 [CREATE TABLE AS](ctas.md) 查询或在 AWS Glue 中运行任务。
+ 您可以使用 `CREATE TABLE AS` (CTAS) 查询一步将数据转换为 Parquet 或 ORC。有关示例，请参阅 [CTAS 查询的示例](ctas-examples.md) 页面上的[示例：将查询结果写入不同的格式](https://docs.aws.amazon.com/athena/latest/ug/ctas-examples.html#ctas-example-format)。
+ 有关使用 Athena for ETL 将数据从 CSV 转换为 Parquet 的信息，请参阅[将 CTAS 和 INSERT INTO 用于 ETL 和数据分析](ctas-insert-into-etl.md)。
+ 有关运行 AWS Glue 任务以将 CSV 数据转换为 Parquet 的信息，请参阅 AWS 大数据博客文章 [使用 AWS Glue 和 Simple Storage Service (Amazon S3) 构建数据湖基础](https://aws.amazon.com/blogs/big-data/build-a-data-lake-foundation-with-aws-glue-and-amazon-s3/)中的“将数据从 CSV 转换为 Parquet 格式”。AWS Glue 支持使用相同的技术将 CSV 数据转换为 ORC，或将 JSON 数据转换为 Parquet 或 ORC。

# 使用分区和分桶
<a name="ctas-partitioning-and-bucketing"></a>

分区和分桶是减少运行查询时 Athena 必须扫描的数据量的两种方法。分区与分区互补，可以一起使用。可通过减少扫描的数据量提高性能并降低成本。有关 Athena 查询性能的一般准则，请参阅 [Amazon Athena 的十大性能优化技巧](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/)。

**Topics**
+ [什么是分区？](ctas-partitioning-and-bucketing-what-is-partitioning.md)
+ [什么是分桶？](ctas-partitioning-and-bucketing-what-is-bucketing.md)
+ [其他资源](ctas-partitioning-and-bucketing-additional-resources.md)

# 什么是分区？
<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)。

# 什么是分桶？
<a name="ctas-partitioning-and-bucketing-what-is-bucketing"></a>

分桶是一种将数据集记录分为称为存储桶的类别的方法。

这里的存储桶和分桶的含义与 Amazon S3 存储桶不同，不应与之混淆。在数据分桶中，具有相同属性值的记录会进入同一存储桶中。记录在存储桶之间尽可能均匀地分布，因此每个存储桶的数据量大致相同。

实际上，存储桶就是文件，哈希函数决定了记录进入哪个存储桶。分桶数据集的每个分区的每个存储桶将包含一个或多个文件。文件所属的存储桶以文件名编码。

## 分桶优势
<a name="ctas-partitioning-and-bucketing-bucketing-benefits"></a>

如果数据集按特定属性进行分桶，并且您想要检索该属性具有特定值的记录，建议使用分桶。由于数据已分桶，Athena 可以使用该值来确定要查看的文件。例如，假设一个数据集按 `customer_id` 进行分桶，并且您想要查找特定客户的所有记录。Athena 确定包含这些记录的存储桶，并且仅读取该存储桶中的文件。

如果您的列具有高基数（即具有许多不同值）、分布均匀且您经常查询特定值，这些都适合作为分桶的依据。

**注意**  
Athena 不支持使用 `INSERT INTO` 向分桶表添加新记录。

## 对分桶列进行筛选所支持的数据类型
<a name="ctas-partitioning-and-bucketing-data-types-supported-for-filtering-on-bucketed-columns"></a>

您可以在具有特定数据类型的分桶列中添加筛选器。Athena 在具有以下数据类型的分桶列上支持筛选：
+ BOOLEAN
+ BYTE
+ DATE
+ DOUBLE
+ FLOAT
+ INT
+ LONG
+ SHORT
+ string
+ VARCHAR

## Hive 和 Spark 支持
<a name="ctas-partitioning-and-bucketing-hive-and-spark-support"></a>

Athena 引擎版本 2 支持使用 Hive 存储桶算法对数据集进行分区，而 Athena 引擎版本 3 也支持 Apache Spark 分桶算法。Hive 分桶为默认设置。如果您的数据集使用 Spark 算法进行分桶，使用 `TBLPROPERTIES` 子句将 `bucketing_format` 属性值设置为 `spark`。

**注意**  
在一个 `CREATE TABLE AS SELECT`（[CTAS](ctas.md)）查询中，Athena 的分区数量不能超过 100 个。同样，您可以使用 [INSERT INTO](insert-into.md) 语句向目标表最多添加 100 个分区。  
如果超过此限制，则可能会收到错误消息 HIVE\$1TOO\$1MANY\$1OPEN\$1PARTITIONS: Exceeded limit of 100 open writers for partitions/buckets（HIVE\$1TOO\$1MANY\$1OPEN\$1PARTITIONS：分区/存储桶超过 100 个打开的写入程序限制）。要绕过此限制，您可以使用一个 CTAS 语句和一系列 `INSERT INTO` 语句，每个后一种语句将创建或插入不超过 100 个分区。有关更多信息，请参阅 [使用 CTAS 和 INSERT INTO 绕过 100 分区限制](ctas-insert-into.md)。

## 分桶 CREATE TABLE 示例
<a name="ctas-partitioning-and-bucketing-bucketing-create-table-example"></a>

要为现有分桶数据集创建表，使用 `CLUSTERED BY (column)` 子句后跟 `INTO N BUCKETS` 子句。`INTO N BUCKETS` 子句指定用于对数据进行分桶的存储桶数。

在以下 `CREATE TABLE` 示例中，使用 Spark 算法按 `customer_id` 将 `sales` 数据集分为 8 个存储桶。`CREATE TABLE` 语句使用 `CLUSTERED BY` 和 `TBLPROPERTIES` 子句相应地设置属性。

```
CREATE EXTERNAL TABLE sales (...) 
... 
CLUSTERED BY (`customer_id`) INTO 8 BUCKETS 
... 
TBLPROPERTIES ( 
  'bucketing_format' = 'spark' 
)
```

## 分桶 CREATE TABLE AS（CTAS）示例
<a name="ctas-partitioning-and-bucketing-bucketing-create-table-as-example"></a>

要使用 `CREATE TABLE AS` 指定分桶，使用 `bucketed_by` 和 `bucket_count` 参数，如以下示例所示。

```
CREATE TABLE sales 
WITH ( 
  ... 
  bucketed_by = ARRAY['customer_id'], 
  bucket_count = 8 
) 
AS SELECT ...
```

## 分桶查询示例
<a name="ctas-partitioning-and-bucketing-bucketing-query-example"></a>

以下示例查询将查找特定客户在一周内购买的产品的名称。

```
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 最多读取每个分区中的一个文件。

# 其他资源
<a name="ctas-partitioning-and-bucketing-additional-resources"></a>
+ 有关创建分桶表和分区表的 `CREATE TABLE AS` 示例，请参阅[示例：创建分桶表和分区表](https://docs.aws.amazon.com/athena/latest/ug/ctas-examples.html#ctas-example-bucketed)。
+ 有关在 AWS 数据湖上实施存储桶的信息，包括对 Apache Spark 使用 Athena CTAS 语句 AWS Glue 以及对 Apache Iceberg 表使用存储桶，请参阅 AWS 大数据博客文章 [Optimize data layout by bucketing with Amazon Athena and AWS Glue to accelerate downstream queries](https://aws.amazon.com/blogs/big-data/optimize-data-layout-by-bucketing-with-amazon-athena-and-aws-glue-to-accelerate-downstream-queries/)。

# 对您的数据进行分区
<a name="partitions"></a>

通过分区您的数据，您可以限制每个查询扫描的数据量，从而提高性能并降低成本。您可按任何键对数据进行分区。一种常见的做法是根据时间对数据进行分区，通常会导致多级别分区方案。例如，每个小时都有数据传入的客户可能决定按年、月、日期和小时进行分区。另一位客户的数据来自许多不同的来源，但每天只加载一次，则可以按数据源标识符和日期进行分区。

Athena 可以使用 Apache Hive 风格的分区，其数据路径包含通过等号连接的键值对（例如，`country=us/...` 或 `year=2021/month=01/day=26/...`）。因此，路径包含分区键的名称和每个路径所表示的值。要将新的 Hive 分区加载到分区表中，您可以使用仅适用于 Hive 风格分区的 [MSCK REPAIR TABLE](msck-repair-table.md) 命令。

Athena 还可以使用非 Hive 风格的分区方案。例如，CloudTrail 日志和 Firehose 传输流在日期部分使用单独的路径组件，例如 `data/2021/01/26/us/6fc7845e.json`。对于此类非 Hive 样式的分区，您可以使用 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) 来手动添加分区。

## 注意事项和限制
<a name="partitions-considerations-limitations"></a>

在使用分区时，请记住以下几点：
+ 如果您查询分区表并在 `WHERE` 子句中指定分区，Athena 仅从该分区扫描数据。
+ 如果您针对包含大量对象且数据未分区的 Amazon S3 存储桶发出查询，则此类查询可能影响 Amazon S3 中的 `GET` 请求速率限制并导致 Amazon S3 异常。为防止错误发生，请将数据分区。另外，考虑调整 Amazon S3 的请求速率。有关更多信息，请参阅[最佳实践设计模式：优化 Simple Storage Service (Amazon S3) 性能](https://docs.aws.amazon.com/AmazonS3/latest/userguide/request-rate-perf-considerations.html)。
+ 要与 Athena 结合使用的分区位置必须使用 `s3` 协议（例如，`s3://amzn-s3-demo-bucket/folder/`）。在 Athena 中，当对包含的表运行 `MSCK REPAIR TABLE` 查询时，使用其他协议的位置（例如，`s3a://amzn-s3-demo-bucket/folder/`）将导致查询失败。
+ 确保 Amazon S3 路径为小写而不是驼峰式大小写（例如，`userid` 而不是 `userId`）。如果 S3 路径为驼峰式大小写，则 `MSCK REPAIR TABLE` 不会将分区添加到 AWS Glue Data Catalog。有关更多信息，请参阅 [MSCK REPAIR TABLE](msck-repair-table.md)。
+ 由于 `MSCK REPAIR TABLE` 同时扫描文件夹及其子文件夹以查找匹配的分区方案，请确保在单独的文件夹层次结构中保留单独表的数据。例如，假设您在 `s3://amzn-s3-demo-bucket1` 中拥有表 1 的数据，在 `s3://amzn-s3-demo-bucket1/table-2-data` 中拥有表 2 的数据。如果两个表都是按字符串分区的，则 `MSCK REPAIR TABLE` 会将表 2 的分区添加到表 1 中。为了避免这种情况，请使用单独的文件夹结构，如 `s3://amzn-s3-demo-bucket1` 和 `s3://amzn-s3-demo-bucket2`。请注意，此行为与 Amazon EMR 和 Apache Hive 一致。
+ 如果将 AWS Glue Data Catalog 与 Athena 一起使用，请参阅 [AWS Glue 端点和限额](https://docs.aws.amazon.com/general/latest/gr/glue.html)，以了解每账户和每表的分区服务限额。
  + 尽管 Athena 支持查询具有 1000 万个分区的 AWS Glue 表，但 Athena 的单次扫描读取量最多为 100 万个分区。在这种情况下，分区索引可能有益。有关更多信息，请参阅 AWS 大数据博客文章：[使用 AWS Glue Data Catalog 分区索引提高 Amazon Athena 查询性能](https://aws.amazon.com/blogs/big-data/improve-amazon-athena-query-performance-using-aws-glue-data-catalog-partition-indexes/)。
+ 如果您使用的是 AWS Glue Data Catalog，请求增加分区限额，请访问 [AWS Glue 的服务限额控制台](https://console.aws.amazon.com/servicequotas/home?region=us-east-1#!/services/glue/quotas)。

## 使用分区数据创建和加载表
<a name="partitions-creating-loading"></a>

要创建使用分区的表，请在 [CREATE TABLE](create-table.md) 语句中使用 `PARTITIONED BY` 子句。`PARTITIONED BY` 子句定义了对数据进行分区所用的键，如以下示例所示。`LOCATION` 子句指定了分区数据的根位置。

```
CREATE EXTERNAL TABLE users (
first string,
last string,
username string
)
PARTITIONED BY (id string)
STORED AS parquet
LOCATION 's3://amzn-s3-demo-bucket'
```

创建表之后，您在分区中加载数据以进行查询。对于 Hive 样式的分区，您可以运行 [MSCK REPAIR TABLE](msck-repair-table.md)。对于非 Hive 样式的分区，您可以使用 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) 来手动添加分区。

## 准备 Hive 风格和非 Hive 风格的数据用于查询
<a name="partitions-preparing-data"></a>

以下部分介绍了如何准备 Hive 风格和非 Hive 风格的数据以便在 Athena 中查询。

### 场景 1：以 Hive 格式存储在 Amazon S3 上的数据
<a name="scenario-1-data-already-partitioned-and-stored-on-s3-in-hive-format"></a>

在此场景中，分区存储在 Amazon S3 中的单独文件夹内。例如，以下是由 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/ls.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/ls.html) 命令输出的示例广告展示的部分列表，其中列出了指定前缀下的 S3 对象：

```
aws s3 ls s3://elasticmapreduce/samples/hive-ads/tables/impressions/

    PRE dt=2009-04-12-13-00/
    PRE dt=2009-04-12-13-05/
    PRE dt=2009-04-12-13-10/
    PRE dt=2009-04-12-13-15/
    PRE dt=2009-04-12-13-20/
    PRE dt=2009-04-12-14-00/
    PRE dt=2009-04-12-14-05/
    PRE dt=2009-04-12-14-10/
    PRE dt=2009-04-12-14-15/
    PRE dt=2009-04-12-14-20/
    PRE dt=2009-04-12-15-00/
    PRE dt=2009-04-12-15-05/
```

日志存储在这里，列名称 (DT) 设置为等于日期、小时和分钟增量。当您向 DDL 提供父文件夹的位置、架构和分区列的名称时，Athena 可以查询这些子文件夹中的数据。

#### 创建表
<a name="creating-a-table"></a>

要从此类数据中生成一个表，请连同“dt”一起创建一个分区，如以下 Athena DDL 语句所示：

```
CREATE EXTERNAL TABLE impressions (
    requestBeginTime string,
    adId string,
    impressionId string,
    referrer string,
    userAgent string,
    userCookie string,
    ip string,
    number string,
    processId string,
    browserCookie string,
    requestEndTime string,
    timers struct<modelLookup:string, requestTime:string>,
    threadId string,
    hostname string,
    sessionId string)
PARTITIONED BY (dt string)
ROW FORMAT  serde 'org.apache.hive.hcatalog.data.JsonSerDe'
LOCATION 's3://elasticmapreduce/samples/hive-ads/tables/impressions/' ;
```

此表使用 Hive 的本机 JSON 串行器/解串器来读取在 Amazon S3 中存储的 JSON 数据。有关支持的格式的更多信息，请参阅[为您的数据选择 SerDE](supported-serdes.md)。

#### 运行 MSCK REPAIR TABLE
<a name="run-msck-repair-table"></a>

运行 `CREATE TABLE` 查询后，在 Athena 查询编辑器中运行 `MSCK REPAIR TABLE` 命令来加载分区，如以下示例所示。

```
MSCK REPAIR TABLE impressions
```

运行此命令后，即可进行数据查询。

#### 查询数据
<a name="query-the-data"></a>

使用分区列从展示表中查询数据。示例如下：

```
SELECT dt,impressionid FROM impressions WHERE dt<'2009-04-12-14-00' and dt>='2009-04-12-13-00' ORDER BY dt DESC LIMIT 100
```

此查询应显示与以下内容类似的结果：

```
2009-04-12-13-20    ap3HcVKAWfXtgIPu6WpuUfAfL0DQEc
2009-04-12-13-20    17uchtodoS9kdeQP1x0XThKl5IuRsV
2009-04-12-13-20    JOUf1SCtRwviGw8sVcghqE5h0nkgtp
2009-04-12-13-20    NQ2XP0J0dvVbCXJ0pb4XvqJ5A4QxxH
2009-04-12-13-20    fFAItiBMsgqro9kRdIwbeX60SROaxr
2009-04-12-13-20    V4og4R9W6G3QjHHwF7gI1cSqig5D1G
2009-04-12-13-20    hPEPtBwk45msmwWTxPVVo1kVu4v11b
2009-04-12-13-20    v0SkfxegheD90gp31UCr6FplnKpx6i
2009-04-12-13-20    1iD9odVgOIi4QWkwHMcOhmwTkWDKfj
2009-04-12-13-20    b31tJiIA25CK8eDHQrHnbcknfSndUk
```

### 方案 2：数据未以 Hive 格式进行分区
<a name="scenario-2-data-is-not-partitioned"></a>

在以下示例中，`aws s3 ls` 命令显示存储在 Amazon S3 中的 [ELB](elasticloadbalancer-classic-logs.md) 日志。请注意，数据布局不使用 `key=value` 对，因此不是 Hive 格式。（`aws s3 ls` 命令的 `--recursive` 选项指定了列出的指定目录或前缀下的所有文件或对象。）

```
aws s3 ls s3://athena-examples-myregion/elb/plaintext/ --recursive

2016-11-23 17:54:46   11789573 elb/plaintext/2015/01/01/part-r-00000-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:46    8776899 elb/plaintext/2015/01/01/part-r-00001-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:46    9309800 elb/plaintext/2015/01/01/part-r-00002-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47    9412570 elb/plaintext/2015/01/01/part-r-00003-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47   10725938 elb/plaintext/2015/01/01/part-r-00004-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:46    9439710 elb/plaintext/2015/01/01/part-r-00005-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47          0 elb/plaintext/2015/01/01_$folder$
2016-11-23 17:54:47    9012723 elb/plaintext/2015/01/02/part-r-00006-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47    7571816 elb/plaintext/2015/01/02/part-r-00007-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47    9673393 elb/plaintext/2015/01/02/part-r-00008-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48   11979218 elb/plaintext/2015/01/02/part-r-00009-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48    9546833 elb/plaintext/2015/01/02/part-r-00010-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48   10960865 elb/plaintext/2015/01/02/part-r-00011-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48          0 elb/plaintext/2015/01/02_$folder$
2016-11-23 17:54:48   11360522 elb/plaintext/2015/01/03/part-r-00012-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48   11211291 elb/plaintext/2015/01/03/part-r-00013-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48    8633768 elb/plaintext/2015/01/03/part-r-00014-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49   11891626 elb/plaintext/2015/01/03/part-r-00015-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49    9173813 elb/plaintext/2015/01/03/part-r-00016-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49   11899582 elb/plaintext/2015/01/03/part-r-00017-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49          0 elb/plaintext/2015/01/03_$folder$
2016-11-23 17:54:50    8612843 elb/plaintext/2015/01/04/part-r-00018-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50   10731284 elb/plaintext/2015/01/04/part-r-00019-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50    9984735 elb/plaintext/2015/01/04/part-r-00020-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50    9290089 elb/plaintext/2015/01/04/part-r-00021-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50    7896339 elb/plaintext/2015/01/04/part-r-00022-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    8321364 elb/plaintext/2015/01/04/part-r-00023-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51          0 elb/plaintext/2015/01/04_$folder$
2016-11-23 17:54:51    7641062 elb/plaintext/2015/01/05/part-r-00024-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51   10253377 elb/plaintext/2015/01/05/part-r-00025-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    8502765 elb/plaintext/2015/01/05/part-r-00026-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51   11518464 elb/plaintext/2015/01/05/part-r-00027-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    7945189 elb/plaintext/2015/01/05/part-r-00028-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    7864475 elb/plaintext/2015/01/05/part-r-00029-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51          0 elb/plaintext/2015/01/05_$folder$
2016-11-23 17:54:51   11342140 elb/plaintext/2015/01/06/part-r-00030-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    8063755 elb/plaintext/2015/01/06/part-r-00031-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    9387508 elb/plaintext/2015/01/06/part-r-00032-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    9732343 elb/plaintext/2015/01/06/part-r-00033-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52   11510326 elb/plaintext/2015/01/06/part-r-00034-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    9148117 elb/plaintext/2015/01/06/part-r-00035-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52          0 elb/plaintext/2015/01/06_$folder$
2016-11-23 17:54:52    8402024 elb/plaintext/2015/01/07/part-r-00036-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    8282860 elb/plaintext/2015/01/07/part-r-00037-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52   11575283 elb/plaintext/2015/01/07/part-r-00038-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53    8149059 elb/plaintext/2015/01/07/part-r-00039-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53   10037269 elb/plaintext/2015/01/07/part-r-00040-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53   10019678 elb/plaintext/2015/01/07/part-r-00041-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53          0 elb/plaintext/2015/01/07_$folder$
2016-11-23 17:54:53          0 elb/plaintext/2015/01_$folder$
2016-11-23 17:54:53          0 elb/plaintext/2015_$folder$
```

#### 运行 ALTER TABLE ADD PARTITION
<a name="run-alter-table-add-partition"></a>

由于数据不是 Hive 格式，因此创建表后，您不能使用 `MSCK REPAIR TABLE` 命令将分区添加到表中。相反，您可以使用 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) 命令手动添加每个分区。例如，要加载 s3://athena-examples-*myregion*/elb/plaintext/2015/01/01/ 中的数据，您可以运行以下查询。请注意，对于每个 Amazon S3 文件夹不需要单独的分区列，并且分区键值可能与 Amazon S3 键不同。

```
ALTER TABLE elb_logs_raw_native_part ADD PARTITION (dt='2015-01-01') location 's3://athena-examples-us-west-1/elb/plaintext/2015/01/01/'
```

如果分区已经存在，您会收到错误 Partition already exists（分区已存在）。要避免此错误，您可以使用 `IF NOT EXISTS` 子句。有关更多信息，请参阅 [ALTER TABLE ADD PARTITION](alter-table-add-partition.md)。要删除分区，您可以使用 [ALTER TABLE DROP PARTITION](alter-table-drop-partition.md)。

## 考虑分区投影
<a name="partitions-partition-projection"></a>

要避免必须自行管理分区，您可以使用分区投影。对于预先知道其结构的高度分区表，分区投影是一个选项。在分区投影中，分区值和位置是根据配置的表属性计算得出的，而不是从元数据存储库中读取出的。由于内存式计算比远程查找更快，因此使用分区投影可以显著减少查询运行时。

有关更多信息，请参阅 [将分区投影与 Amazon Athena 结合使用](partition-projection.md)。

## 其他资源
<a name="partitions-additional-resources"></a>
+ 有关 Firehose 数据分区选项的信息，请参阅 [Amazon Data Firehose 示例](partition-projection-kinesis-firehose-example.md)。
+ 您可以通过使用 [JDBC 驱动程序](connect-with-jdbc.md)自动添加分区。
+ 您可以使用 CTAS 和 INSERT INTO 对数据集进行分区。有关更多信息，请参阅 [将 CTAS 和 INSERT INTO 用于 ETL 和数据分析](ctas-insert-into-etl.md)。

# 将分区投影与 Amazon Athena 结合使用
<a name="partition-projection"></a>

可以在 Athena 中使用分区投影来加快对高度分区表的查询处理，并自动执行分区管理。

在分区投影中，Athena 使用直接在 AWS Glue 表上配置的表属性计算分区值和位置。表属性允许 Athena“投影”或确定必要的分区信息，无需在 AWS Glue Data Catalog 中进行更耗时的元数据查找。由于内存中的操作通常快于远程操作，因此，分区投影可以减少针对高度分区表的查询的运行时间。根据查询和基础数据的具体特征，分区投影可以显著减少在分区元数据检索方面受到限制的查询的运行时间。

## 了解分区修剪与分区投影
<a name="partition-projection-pruning-vs-projection"></a>

分区修剪将收集元数据并对其进行“修剪”，以便只存在适用于查询的分区。这通常会加快查询速度。Athena 对所有带分区列的表（包括为分区投影配置的表）使用分区修剪。

通常，在处理查询时，Athena 会在执行分区修剪之前向 AWS Glue Data Catalog 发出 `GetPartitions` 调用。如果表具有大量分区，则使用 `GetPartitions` 会导致性能降低。要避免发生此情况，您可以使用分区投影。分区投影可让 Athena 避免调用 `GetPartitions`，因为分区投影配置为 Athena 提供了自行构建分区所需的所有信息。

## 如何使用分区投影
<a name="partition-projection-using"></a>

要使用分区投影，请在 AWS Glue Data Catalog 或[外部 Hive 元存储](connect-to-data-source-hive.md)中的表属性中为每个分区列指定分区值和投影类型的范围。表的这些自定义属性可让 Athena 了解在对表运行查询时应使用哪种分区模式。在查询执行期间，Athena 使用此信息对分区值进行投影，而不是从 AWS Glue Data Catalog 或外部 Hive 元存储中检索这些值。这不仅将减少查询执行时间，还将自动执行分区管理，因为不再需要在 Athena、AWS Glue 或外部 Hive 元存储中手动创建分区。

**重要**  
在表上启用分区投影会导致 Athena 忽略在 AWS Glue Data Catalog 或 Hive 元存储中注册到表的任何分区元数据。

## 一些使用案例
<a name="partition-projection-use-cases"></a>

分区投影在许多场景中都很有用，其中包括：
+ 对高度分区表的查询不会像您希望的那样快速完成。
+ 在数据中创建新的日期或时间分区时，可以定期向表添加分区。利用分区投影，可以配置可在新数据到达时使用的相对日期范围。
+ 您在 Amazon S3 中有高度分区的数据。在 AWS Glue Data Catalog 或 Hive 元存储中为数据建模是不切实际的，并且您的查询仅读取其中的一小部分。

### 可投影的分区结构
<a name="partition-projection-known-data-structures"></a>

当您的分区遵循可预测的模式时（包括但不限于以下情况），分区投影最易配置：
+ **整数** – 任何连续的整数序列，例如 `[1, 2, 3, 4, ..., 1000]` 或 `[0500, 0550, 0600, ..., 2500]`。
+ **日期** – 任何连续的日期或日期时间序列，例如 `[20200101, 20200102, ..., 20201231]` 或 `[1-1-2020 00:00:00, 1-1-2020 01:00:00, ..., 12-31-2020 23:00:00]`。
+ **枚举值** – 一组有限的枚举值，例如机场代码或 AWS 区域。
+ **AWS 服务 日志** – AWS 服务 日志通常具有一个已知结构，您可以在 AWS Glue 中指定该结构的分区方案，并且 Athena 可以将其用于分区投影。

### 如何自定义分区路径模板
<a name="partition-projection-custom-s3-storage-locations"></a>

预设情况下，Athena 使用 `s3://amzn-s3-demo-bucket/<table-root>/partition-col-1=<partition-col-1-val>/partition-col-2=<partition-col-2-val>/` 格式生成分区位置，但如果您数据的组织方式不同，则 Athena 会提供用于自定义此路径模板的机制。要查看步骤，请参阅[如何指定自定义 S3 存储位置](partition-projection-setting-up.md#partition-projection-specifying-custom-s3-storage-locations)。

## 注意事项和限制
<a name="partition-projection-considerations-and-limitations"></a>

请注意以下事项：
+ 有了分区投影，便无需在 AWS Glue 或外部 Hive 元存储中手动指定分区。
+ 在表上启用分区投影时，Athena 将为该表忽略 AWS Glue Data Catalog 或外部 Hive 元存储中的任何分区元数据。
+ 如果 Amazon S3 中没有投影分区，Athena 仍会对分区进行投影。Athena 不会引发错误，但也未返回任何数据。不过，如果您的空分区过多，则性能会低于传统的 AWS Glue 分区。如果有一半以上的投影分区为空，建议您使用传统分区。
+ 超出为分区投影定义的范围边界的值的查询不会返回错误。相反，查询将会运行，但返回零行。例如，如果您的时间相关数据从 2020 年开始，并且定义为 `'projection.timestamp.range'='2020/01/01,NOW'`，一个类似 `SELECT * FROM table-name WHERE timestamp = '2019/02/02'` 的查询将成功执行，但将返回零行。
+ 分区投影仅在通过 Athena 查询表时可用。如果通过其他服务（例如 Amazon Redshift Spectrum、Athena for Spark 或 Amazon EMR）读取同一个表，则使用标准分区元数据。
+ 由于分区投影是一项仅限 DML 的功能，因此 `SHOW PARTITIONS` 不会列出由 Athena 投影但未注册到 AWS Glue 目录或外部 Hive 元存储中的分区。
+ Athena 不使用视图的表属性作为分区投影的配置。要变通解决此限制，请在视图引用的表的表属性中配置和启用分区投影。

## 视频
<a name="partition-projection-video"></a>

下面的视频演示了如何使用分区投影来提高 Athena 中查询的性能。

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/iUD5pPpcyZk/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/iUD5pPpcyZk)


**Topics**
+ [了解分区修剪与分区投影](#partition-projection-pruning-vs-projection)
+ [如何使用分区投影](#partition-projection-using)
+ [一些使用案例](#partition-projection-use-cases)
+ [注意事项和限制](#partition-projection-considerations-and-limitations)
+ [视频](#partition-projection-video)
+ [设置分区投影](partition-projection-setting-up.md)
+ [受支持的分区投影类型](partition-projection-supported-types.md)
+ [使用动态 ID 分区](partition-projection-dynamic-id-partitioning.md)
+ [Amazon Data Firehose 示例](partition-projection-kinesis-firehose-example.md)

# 设置分区投影
<a name="partition-projection-setting-up"></a>

在表的属性中设置分区投影是一个包含两个步骤的过程：

1. 指定每个分区列的数据范围和相关模式，或使用自定义模板。

1. 为表启用分区投影。

**注意**  
在向现有表添加分区投影属性之前，要为其设置分区投影属性的分区列必须已存在于表架构中。如果分区列尚不存在，则必须将分区列手动添加到现有表中。AWS Glue 不会自动为您执行此步骤。

本节介绍如何为 AWS Glue 设置表属性。要设置这些表属性，您可以使用 AWS Glue 控制台、Athena [CREATE TABLE](create-table.md) 查询或 [AWS Glue API](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api.html) 操作。以下过程说明如何在 AWS Glue 控制台中设置属性。

**要使用 AWS Glue 控制台配置并启用分区投影**

1. 登录 AWS 管理控制台，然后打开 AWS Glue 控制台，网址为：[https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/)。

1. 选择 **Tables (表)** 选项卡。

   在 **Tables (表)** 选项卡上，您可以编辑现有表，也可以选择 **Add tables (添加表)** 来创建新表。有关手动添加表或使用爬网程序添加表的信息，请参阅《AWS Glue 开发人员指南**》中的[在 AWS Glue 控制台上使用表](https://docs.aws.amazon.com/glue/latest/dg/console-tables.html)。

1. 在表的列表中，选择要编辑的表的链接。  
![\[在 AWS Glue 控制台中，选择要编辑的表。\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/partition-projection-1.png)

1. 依次选择 **Actions**（操作）、**Edit table**（编辑表）。

1. 在 **Edit table**（编辑表）页面的 **Table properties**（表属性）部分中，对于每个分区列，添加以下键值对：

   1. 对于 **Key (键)**，添加 `projection.columnName.type`。

   1. 对于 **Value (值)**，添加受支持的类型之一：`enum`、`integer`、`date` 或 `injected`。有关更多信息，请参阅 [受支持的分区投影类型](partition-projection-supported-types.md)。

1. 按照[受支持的分区投影类型](partition-projection-supported-types.md)中的指导信息进行操作，根据配置要求添加其他键/值对。

   以下示例表配置将为分区投影配置 `year` 列，从而将可返回的值限定为 2010 年至 2016 年的数据。  
![\[在 AWS Glue 控制台表属性中配置分区列的分区投影。\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/partition-projection-3.png)

1. 添加键/值对以启用分区投影。对于 **Key (键)**，输入 `projection.enabled`，对于其 **Value (值)**，输入 `true`。
**注意**  
您可以随时通过将 `projection.enabled` 设置为 `false` 来对此表禁用分区投影。

1. 完成后，选择 **Save**。

1. 在 Athena 查询编辑器中，测试查询为表配置的列。

   以下示例查询使用 `SELECT DISTINCT` 从 `year` 列返回唯一值。数据库包含 1987 年至 2016 年的数据，但 `projection.year.range` 属性将返回的值限定为 2010 年至 2016 年的数据。  
![\[查询使用分区投影的列。\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/partition-projection-5.png)
**注意**  
如果将 `projection.enabled` 设置为 `true`，但未能配置一个或多个分区列，则会收到与以下内容类似的错误消息：  
`HIVE_METASTORE_ERROR: Table database_name.table_name is configured for partition projection, but the following partition columns are missing projection configuration: [column_name] (table database_name.table_name)`.

## 如何指定自定义 S3 存储位置
<a name="partition-projection-specifying-custom-s3-storage-locations"></a>

在 AWS Glue 中编辑表属性时，还可以为投影分区指定自定义 Amazon S3 路径模板。利用自定义模板，Athena 可以将分区值正确映射到未遵循典型 `.../column=value/...` 模式的自定义 Amazon S3 文件位置。

可以选择使用自定义模板。但是，如果您使用自定义模板，则该模板中必须为每个分区列包含一个占位符。模板化位置必须以正斜杠结尾，以便分区的数据文件位于每个分区的“文件夹”中。

**指定自定义分区位置模板**

1. 按照步骤[使用 AWS Glue 控制台配置并启用分区投影](#partition-projection-setting-up-procedure)，添加一个指定自定义模板的附加键/值对，如下所示：

   1. 对于**键**，输入 `storage.location.template`。

   1. 对于 **Value (值)**，指定一个位置，该位置为每个分区列包含一个占位符。确保每个占位符(和 S3 路径本身)都以单个正斜杠结束。

      以下示例模板值假定一个具有分区列 `a`、`b` 和 `c` 的表。

      ```
      s3://amzn-s3-demo-bucket/table_root/a=${a}/${b}/some_static_subdirectory/${c}/      
      ```

      ```
      s3://amzn-s3-demo-bucket/table_root/c=${c}/${b}/some_static_subdirectory/${a}/${b}/${c}/${c}/      
      ```

      对于同一个表，以下示例模板值无效，因为它不包含列 `c` 的占位符。

      ```
      s3://amzn-s3-demo-bucket/table_root/a=${a}/${b}/some_static_subdirectory/         
      ```

1. 选择**应用**。

# 受支持的分区投影类型
<a name="partition-projection-supported-types"></a>

表可以具有 `enum`、`integer`、`date,` 或 `injected` 分区列类型的任意组合。

## 枚举类型
<a name="partition-projection-enum-type"></a>

将 `enum` 类型用于其值为枚举集成员（例如，机场代码或 AWS 区域）的分区列。

在表中定义分区属性，如下所示：


****  

| 属性名称 | 示例值 | 说明 | 
| --- | --- | --- | 
| projection.columnName.type |  `enum`  | 必需。要用于 columnName 列的投影类型。该值必须是 enum（不区分大小写）才能发出使用枚举类型的信号。允许前导和尾随空格。 | 
| projection.columnName.values |  `A,B,C,D,E,F,G,Unknown`  | 必需。columnName 列的枚举分区值的逗号分隔列表。任何空格均被视为枚举值的一部分。 | 

**注意**  
作为最佳实践，我们建议将基于 `enum` 的分区投影使用数量限制在数十个或更少的范围。虽然 `enum` 投影没有特定限制，但表元数据的总大小在 gzip 压缩时不能超过约 1 MB 的 AWS Glue 限制。请注意，此限制将在表格的关键部分（如列名称、位置、存储格式和其他部分）之间共享。如果您发现自己在 `enum` 投影使用的唯一 ID 多于数十个，请考虑一种替代方法，例如在代理字段中分桶为较少数量的唯一值。通过折衷基数，您可以控制 `enum` 字段中返回的唯一值数量。

## 整数类型
<a name="partition-projection-integer-type"></a>

将整数类型用于其可能的值可被解释为定义的范围内的整数的分区列。投影整数列目前仅限于 Java 有符号长整型值的范围（-263 到 263-1，含这两个值）。


****  

| 属性名称 | 示例值 | 说明 | 
| --- | --- | --- | 
| projection.columnName.type |  `integer`  | 必需。要用于 columnName 列的投影类型。该值必须是 integer（不区分大小写）才能发出使用整数类型的信号。允许前导和尾随空格。 | 
| projection.columnName.range |  `0,10` `-1,8675309` `0001,9999`  | 必需。一个包含两个元素的逗号分隔列表，该列表提供将由对 columName 列进行的查询返回的最小范围值和最大范围值。请注意，必须使用逗号来分隔值，而不是使用连字符。这些值包含在内，它们可以是负数，并且可以有前导零。允许前导和尾随空格。 | 
| projection.columnName.interval |  `1` `5`  | 可选。一个正整数，它指定 columName 列的连续分区值之间的间隔。例如，具有 interval 值“1”的 range 值“1,3”将产生值 1、2 和 3。具有 interval 值“2”的相同 range 值将产生值 1 和 3，并跳过 2。允许前导和尾随空格。默认 为 1。 | 
| projection.columnName.digits |  `1` `5`  | 可选。一个正整数，它指定要包含在 columName 列的分区值的最终表示形式中的位数。例如，具有 digits 值“1”的 range 值“1,3”将产生值 1、2 和 3。具有 digits 值“2”的相同 range 值将产生值 01、02 和 03。允许前导和尾随空格。默认值不包含静态位数和前导零。 | 

## 日期类型
<a name="partition-projection-date-type"></a>

将日期类型用于其值可被解释为定义的范围内的日期（带可选时间）的分区列。

**重要**  
投影日期列在查询执行时以协调世界时 (UTC) 格式生成。


****  

| 属性名称 | 示例值 | 说明 | 
| --- | --- | --- | 
| projection.columnName.type |  `date`  | 必需。要用于 columnName 列的投影类型。该值必须是 date（不区分大小写）才能发出使用日期类型的信号。允许前导和尾随空格。 | 
| projection.columnName.range |  `201701,201812` `01-01-2010,12-31-2018` `NOW-3YEARS,NOW` `201801,NOW+1MONTH`  |  必需。一个包含两个元素的逗号分隔列表，该列表提供 *columName* 列的最小范围和最大范围 `range` 值。这些值包含在内，它们可以使用任何与 Java `java.time.*` 日期类型兼容的格式。最小值和最大值必须使用相同的格式。`.format` 属性中指定的格式必须是用于这些值的格式。 此列还可以包含格式为以下正则表达式模式的相对日期字符串： `\s*NOW\s*(([\+\-])\s*([0-9]+)\s*(YEARS?\|MONTHS?\|WEEKS?\|DAYS?\|HOURS?\|MINUTES?\|SECONDS?)\s*)?` 允许使用空格，但在日期中，文本将被视为日期字符串的一部分。  | 
| projection.columnName.format |  `yyyyMM` `dd-MM-yyyy` `dd-MM-yyyy-HH-mm-ss`  | 必需。基于 Java 日期格式 [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) 的日期格式字符串。可以是任何受支持的 Java.time.\$1 类型。 | 
| projection.columnName.interval |  `1` `5`  |  一个正整数，它指定 *columName* 列的连续分区值之间的间隔。例如，具有 `interval` 值 `1` 和 `interval.unit` 值 `MONTHS` 的 `range` 值 `2017-01,2018-12` 将产生值 2017-01、2017-02、2017-03，依此类推。具有 `interval` 值 `2` 和 `interval.unit` 值 `MONTHS` 的相同 `range` 值将产生值 2017-01、2017-03、2017-05，依此类推。允许前导和尾随空格。 如果提供的日期的精度为单日或单月，则 `interval` 是可选的，默认值分别为 1 天或 1 个月。否则，`interval` 是必需的。  | 
| projection.columnName.interval.unit |  `YEARS` `MONTHS` `WEEKS` `DAYS` `HOURS` `MINUTES` `SECONDS` `MILLIS`  |  一个时间单位词，它表示 [ChronoUnit](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoUnit.html) 的序列化形式。可能的值为 `YEARS`、`MONTHS`、`WEEKS`、`DAYS`、`HOURS`、`MINUTES`、`SECONDS` 或 `MILLIS`。这些值不区分大小写。 如果提供的日期的精度为单日或单月，则 `interval.unit` 是可选的，默认值分别为 1 天或 1 个月。否则，`interval.unit` 是必需的。  | 

**Example – 按月分区**  
以下示例表配置按月对 2015 年至今的数据进行分区。  

```
'projection.month.type'='date', 
'projection.month.format'='yyyy-MM', 
'projection.month.interval'='1', 
'projection.month.interval.unit'='MONTHS', 
'projection.month.range'='2015-01,NOW', 
...
```

## 注入的类型
<a name="partition-projection-injected-type"></a>

将注入的类型用于分区列，这些分区列的可能值无法在某个逻辑范围内通过程序生成，而是在查询的 `WHERE` 子句中作为单个值提供。

请务必记住以下几点：
+ 如果未为每个注入列提供筛选条件表达式，则对注入列进行的查询将失败。
+ 对于在注入列上具有多个筛选条件表达式值的查询，只有在这些值分离时，这些查询才会成功。
+ 仅支持 `string` 类型的列。
+ 将 `WHERE IN` 子句与注入的分区列一起使用时，`IN` 列表中最多可以指定 1000 个值。如果要查询的数据集中某个注入的列包含超过 1000 个分区，请将查询拆分为多个较小的查询，使每个查询的 `WHERE IN` 子句中最多包含 1000 个值，然后再聚合结果。


****  

| 属性名称 | 值 | 说明 | 
| --- | --- | --- | 
| projection.columnName.type |  `injected`  | 必需。要用于 columnName 列的投影类型。仅支持 string 类型。指定的值必须是 injected（不区分大小写）。允许前导和尾随空格。 | 

有关更多信息，请参阅 [何时使用 `injected` 投影类型](partition-projection-dynamic-id-partitioning.md#partition-projection-injection)。

# 使用动态 ID 分区
<a name="partition-projection-dynamic-id-partitioning"></a>

当数据按高基数属性分区时，或者无法事先知道这些值时，您可以使用 `injected` 投影类型。此类属性的示例包括用户名以及设备或产品的 ID。当您使用 `injected` 投影类型配置分区键时，Athena 使用查询本身的值来计算要读取的分区集。

如果某个表具有通过 `injected` 投影类型配置的分区键，则要使 Athena 能够在该表上运行查询，必须满足以下条件：
+ 查询必须包括至少一个分区键值。
+ 值必须是无需读取任何数据即可评估的文字或表达式。

只要其中一个条件不满足，查询就会失败，并显示以下错误：

CONSTRAINT\$1VIOLATION：对于注入的投影分区列 *column\$1name*，WHERE 子句必须仅包含静态相等条件，并且必须至少存在一个此类条件。

## 何时使用 `injected` 投影类型
<a name="partition-projection-injection"></a>

设想您的数据集包含来自 IoT 设备的事件，并按设备的 ID 进行分区。该数据集具有以下特征：
+ 设备 ID 随机生成。
+ 新设备经常预置。
+ 目前有数十万台设备，将来会有数百万台。

使用传统的元数据存储很难管理此数据集。难以确保数据存储与元存储之间保持分区同步，而且在查询规划期间筛选分区可能很慢。但是，如果您将表配置为使用分区投影并使用 `injected` 投影类型，您会获得两个优势：您不必在元存储中管理分区，并且您的查询不必查找分区元数据。

以下 `CREATE TABLE` 示例会为刚刚描述的设备事件数据集创建一个表。该表使用注入投影类型。

```
CREATE EXTERNAL TABLE device_events (
  event_time TIMESTAMP,
  data STRING,
  battery_level INT
)
PARTITIONED BY (
  device_id STRING
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
  "projection.enabled" = "true",
  "projection.device_id.type" = "injected",
  "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${device_id}"
)
```

以下示例查询会查找在 12 小时内从三台特定设备收到的事件数。

```
SELECT device_id, COUNT(*) AS events
FROM device_events
WHERE device_id IN (
  '4a770164-0392-4a41-8565-40ed8cec737e',
  'f71d12cf-f01f-4877-875d-128c23cbde17',
  '763421d8-b005-47c3-ba32-cc747ab32f9a'
)
AND event_time BETWEEN TIMESTAMP '2023-11-01 20:00' AND TIMESTAMP '2023-11-02 08:00'
GROUP BY device_id
```

当您运行此查询时，Athena 会看到 `device_id` 分区键的三个值，并使用这些值来计算分区位置。Athena 使用 `storage.location.template` 属性的值来生成以下位置：
+ `s3://amzn-s3-demo-bucket/prefix/4a770164-0392-4a41-8565-40ed8cec737e`
+ `s3://amzn-s3-demo-bucket/prefix/f71d12cf-f01f-4877-875d-128c23cbde17`
+ `s3://amzn-s3-demo-bucket/prefix/763421d8-b005-47c3-ba32-cc747ab32f9a`

如果您在分区投影配置中省略了 `storage.location.template` 属性，Athena 会使用 Hive 风格分区，根据 `LOCATION` 中的值（例如，`s3://amzn-s3-demo-bucket/prefix/device_id=4a770164-0392-4a41-8565-40ed8cec737e`）投影分区位置。

# Amazon Data Firehose 示例
<a name="partition-projection-kinesis-firehose-example"></a>

当您使用 Firehose 将数据传输到 Amazon S3 时，默认配置会使用类似于以下示例的键写入对象：

```
s3://amzn-s3-demo-bucket/prefix/yyyy/MM/dd/HH/file.extension
```

要创建在查询时自动查找分区的 Athena 表，而不必在新数据到达时将它们添加到 AWS Glue Data Catalog，您可以使用分区投影。

以下 `CREATE TABLE` 示例使用了默认 Firehose 配置。

```
CREATE EXTERNAL TABLE my_ingested_data (
 ...
)
...
PARTITIONED BY (
 datehour STRING
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.datehour.type" = "date",
 "projection.datehour.format" = "yyyy/MM/dd/HH",
 "projection.datehour.range" = "2021/01/01/00,NOW",
 "projection.datehour.interval" = "1",
 "projection.datehour.interval.unit" = "HOURS",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${datehour}/"
)
```

`CREATE TABLE` 语句中的 `TBLPROPERTIES` 子句告诉 Athena 以下内容：
+ 查询表时使用分区投影
+ 分区键 `datehour` 的类型为 `date`（包括可选时间）
+ 如何格式化日期
+ 日期时间范围 请注意，必须使用逗号来分隔值，而不是使用连字符。
+ Amazon S3 上数据所在的位置。

当您查询表时，Athena 会计算 `datehour` 值并使用存储位置模板生成分区位置列表。

**Topics**
+ [如何使用 `date` 类型](partition-projection-kinesis-firehose-example-using-the-date-type.md)
+ [如何选择分区键](partition-projection-kinesis-firehose-example-choosing-partition-keys.md)
+ [如何使用自定义前缀和动态分区](partition-projection-kinesis-firehose-example-using-custom-prefixes-and-dynamic-partitioning.md)

# 如何使用 `date` 类型
<a name="partition-projection-kinesis-firehose-example-using-the-date-type"></a>

当您使用投影分区键的 `date` 类型时，您必须指定一个范围。由于在创建 Firehose 传输流之前没有日期数据，您可以使用创建日期作为开始日期。此外，由于您没有将来日期的数据，您可以使用特殊令牌 `NOW` 作为结束日期。

在 `CREATE TABLE` 示例中，开始日期指定为 UTC 时间 2021 年 1 月 1 日午夜。

**注意**  
配置一个与您的数据尽可能匹配的范围，以便 Athena 仅查找现有分区。

在示例表上运行查询时，Athena 将 `datehour` 分区键上的条件与范围结合使用来生成值。请考虑以下查询：

```
SELECT *
FROM my_ingested_data
WHERE datehour >= '2020/12/15/00'
AND datehour < '2021/02/03/15'
```

`SELECT` 查询中的第一个条件使用在 `CREATE TABLE` 语句指定的日期范围开始之前的日期。由于分区投影配置没有为 2021 年 1 月 1 日之前的日期指定分区，因此 Athena 仅在以下位置查找数据，并忽略查询中较早的日期。

```
s3://amzn-s3-demo-bucket/prefix/2021/01/01/00/
s3://amzn-s3-demo-bucket/prefix/2021/01/01/01/
s3://amzn-s3-demo-bucket/prefix/2021/01/01/02/
...
s3://amzn-s3-demo-bucket/prefix/2021/02/03/12/
s3://amzn-s3-demo-bucket/prefix/2021/02/03/13/
s3://amzn-s3-demo-bucket/prefix/2021/02/03/14/
```

同样，如果查询在 2021 年 2 月 3 日 15:00 之前的日期和时间运行，则最后一个分区将反映当前日期和时间，而不是查询条件中的日期和时间。

如果您想查询最新数据，您可以利用 Athena 不生成未来日期的事实，并仅指定起始 `datehour`，如以下示例所示。

```
SELECT *
FROM my_ingested_data
WHERE datehour >= '2021/11/09/00'
```

# 如何选择分区键
<a name="partition-projection-kinesis-firehose-example-choosing-partition-keys"></a>

您可以指定分区投影如何将分区位置映射到分区键。在上一节的 `CREATE TABLE` 示例中，日期和小时组合成一个名为 datehour 的分区键，但也可以使用其他方案。例如，您还可以为年、月、日和小时配置具有单独分区键的表。

不过，将日期拆分为年、月、日意味着无法使用 `date` 分区投影类型。另一种方法是将日期与小时分开，以便仍然利用 `date` 分区投影类型，但要确保用来指定小时范围的查询更加易于阅读。

考虑到这一点，以下 `CREATE TABLE` 示例将日期与小时分开。由于 `date` 是 SQL 中的保留字，因此这一示例使用 `day` 作为表示日期的分区键的名称。

```
CREATE EXTERNAL TABLE my_ingested_data2 (
 ...
)
...
PARTITIONED BY (
 day STRING,
 hour INT
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.day.type" = "date",
 "projection.day.format" = "yyyy/MM/dd",
 "projection.day.range" = "2021/01/01,NOW",
 "projection.day.interval" = "1",
 "projection.day.interval.unit" = "DAYS",
 "projection.hour.type" = "integer",
 "projection.hour.range" = "0,23",
 "projection.hour.digits" = "2",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${day}/${hour}/"
)
```

在示例 `CREATE TABLE` 语句中，小时是一个单独的分区键，配置为整数。小时分区键的配置指定了 0 到 23 的范围，并且当 Athena 生成分区位置时，小时的格式应为两位数。

对 `my_ingested_data2` 表的查询可能如下所示：

```
SELECT *
FROM my_ingested_data2
WHERE day = '2021/11/09'
AND hour > 3
```

## 了解分区键和分区投影数据类型
<a name="partition-projection-kinesis-firehose-example-partition-key-types-and-partition-projection-types"></a>

请注意，第一个 `CREATE TABLE` 示例中的 `datehour` 键在分区投影配置中配置为 `date`，但分区键的类型为 `string`。第二个示例中的 `day` 也是如此。分区投影配置中的类型仅告诉 Athena 在生成分区位置时如何格式化值。您指定的类型不会更改分区键的类型 – 在查询中，`datehour` 和 `day` 属于 `string` 类型。

当查询包含与 `day = '2021/11/09'` 类似的条件时，Athena 会使用分区投影配置中指定的日期格式解析表达式右侧的字符串。在 Athena 验证日期是否在配置范围内后，它会再次使用日期格式将日期作为字符串插入到存储位置模板中。

同样，对于像 `day > '2021/11/09'` 这样的查询条件，Athena 会解析右侧并生成配置范围内所有匹配日期的列表。然后使用日期格式将每个日期插入到存储位置模板中以创建分区位置列表。

编写与 `day > '2021-11-09'` 或 `day > DATE '2021-11-09'` 相同的条件将无效。在第一种情况下，日期格式不匹配（注意连字符而不是正斜杠），在第二种情况下，数据类型不匹配。

# 如何使用自定义前缀和动态分区
<a name="partition-projection-kinesis-firehose-example-using-custom-prefixes-and-dynamic-partitioning"></a>

可以使用[自定义前缀](https://docs.aws.amazon.com/firehose/latest/dev/s3-prefixes.html)和[动态分区](https://docs.aws.amazon.com/firehose/latest/dev/dynamic-partitioning.html)配置 Firehose。使用这些功能，您可以配置 Amazon S3 键并设置更好地支持您的使用案例的分区方案。您还可以将分区投影与这些分区方案一起使用，然后进行相应的配置。

例如，您可以使用自定义前缀功能获取具有 ISO 格式日期而非默认 `yyyy/MM/dd/HH` 方案的 Amazon S3 键。

您还可以将自定义前缀与动态分区结合使用，以便从 Firehose 消息中提取 `customer_id` 之类的属性，如下例所示。

```
prefix/!{timestamp:yyyy}-!{timestamp:MM}-!{timestamp:dd}/!{partitionKeyFromQuery:customer_id}/
```

使用该 Amazon S3 前缀，Firehose 传输流会将对象写入 `s3://amzn-s3-demo-bucket/prefix/2021-11-01/customer-1234/file.extension` 等键。对于像 `customer_id` 这样的属性，其值可能事先未知，您可以使用分区投影类型 `injected` 并使用如下所示的 `CREATE TABLE` 语句：

```
CREATE EXTERNAL TABLE my_ingested_data3 (
 ...
)
...
PARTITIONED BY (
 day STRING,
 customer_id STRING
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.day.type" = "date",
 "projection.day.format" = "yyyy-MM-dd",
 "projection.day.range" = "2021-01-01,NOW",
 "projection.day.interval" = "1",
 "projection.day.interval.unit" = "DAYS",
 "projection.customer_id.type" = "injected",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${day}/${customer_id}/"
)
```

当您查询具有类型 `injected` 的分区键的表时，您的查询必须包含该分区键的值。对 `my_ingested_data3` 表的查询可能如下所示：

```
SELECT *
FROM my_ingested_data3
WHERE day BETWEEN '2021-11-01' AND '2021-11-30'
AND customer_id = 'customer-1234'
```

## 将 DATE 类型用于日期分区键
<a name="partition-projection-kinesis-firehose-example-iso-formatted-dates"></a>

由于 `day` 分区键的值是 ISO 格式的，您也可以使用 `DATE` 类型而不是 `STRING` 类型作为日期分区键，如以下示例所示：

```
PARTITIONED BY (day DATE, customer_id STRING)
```

查询时，此策略允许您在分区键上使用日期函数而无需解析或转换，如以下示例所示：

```
SELECT *
FROM my_ingested_data3
WHERE day > CURRENT_DATE - INTERVAL '7' DAY
AND customer_id = 'customer-1234'
```

**注意**  
指定 `DATE` 类型的分区键时，假设您已使用[自定义前缀](https://docs.aws.amazon.com/firehose/latest/dev/s3-prefixes.html)功能创建了日期为 ISO 格式的 Amazon S3 键。如果您使用默认的 Firehose 格式 `yyyy/MM/dd/HH`，则即使相应表属性的类型为 `date`，也必须将分区键指定为类型 `string`，如下例所示：  

```
PARTITIONED BY ( 
  `mydate` string)
TBLPROPERTIES (
  'projection.enabled'='true', 
   ...
  'projection.mydate.type'='date',
  'storage.location.template'='s3://amzn-s3-demo-bucket/prefix/${mydate}')
```

# 防止 Amazon S3 节流
<a name="performance-tuning-s3-throttling"></a>

节流指限制服务、应用程序或系统使用速率的过程。在 AWS 中，您可以使用节流防止过度使用 Amazon S3 服务，并提高 Amazon S3 对所有用户的可用性和响应能力。但是，由于节流会限制在 Amazon S3 中传入或传出数据的速率，因此必须考虑防止您的交互受到节流。

正如[性能优化](performance-tuning.md)一章所指出的那样，优化可能取决于您的服务级别决策、如何构建表和数据的结构以及如何编写查询。

**Topics**
+ [减少服务级别节流](performance-tuning-s3-throttling-reduce-throttling-at-the-service-level.md)
+ [优化您的表](performance-tuning-s3-throttling-optimizing-your-tables.md)
+ [优化您的查询](performance-tuning-s3-throttling-optimizing-queries.md)

# 减少服务级别节流
<a name="performance-tuning-s3-throttling-reduce-throttling-at-the-service-level"></a>

为了避免服务级别下的 Amazon S3 节流，您可以监控使用情况并调整[服务限额](https://docs.aws.amazon.com/general/latest/gr/s3.html#limits_s3)，也可以使用分区等特定方法。下面是一些可能导致节流的一些情况：
+ **超过账户的 API 请求限制** - Amazon S3 具有基于账户类型和使用情况的默认 API 请求限制。如果超过单个前缀每秒的最大请求数，则可能会对您的请求进行节流，以防 Amazon S3 服务过载。
+ **数据分区不足** - 如果您没有正确分区数据并传输大量数据，Amazon S3 可能会对您的请求进行节流。有关分区的更多信息，请参阅本文档中的 [使用分区](performance-tuning-s3-throttling-optimizing-your-tables.md#performance-tuning-s3-throttling-use-partitioning) 节。
+ **大量小对象** - 如有可能，避免生成大量小文件。Amazon S3 的每个分区前缀每秒最多 [5500 个 GET 请求](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html)，您的 Athena 查询也具有同样的限制。如果您需要在单一查询中扫描数百万个小对象，则 Amazon S3 可能会对您的查询进行节流。

要避免过度扫描，可使用 AWS Glue ETL 定期压缩文件，或者对表进行分区并添加分区键筛选条件。有关详细信息，请参阅以下资源：
+ [如何配置 AWS Glue ETL 作业以输出较大的文件？](https://aws.amazon.com/premiumsupport/knowledge-center/glue-job-output-large-files/) （*AWS 知识中心*）
+ [以较大的组读取输入文件](https://docs.aws.amazon.com/glue/latest/dg/grouping-input-files.html)（《AWS Glue 开发人员指南**》）

# 优化您的表
<a name="performance-tuning-s3-throttling-optimizing-your-tables"></a>

如果您遇到节流问题，则需要对数据进行结构化。尽管 Amazon S3 可以处理大量数据，但由于数据的结构方式，有时也会发生节流。

以下各节就如何在 Amazon S3 中结构化数据以免出现节流问题提供了一些建议。

## 使用分区
<a name="performance-tuning-s3-throttling-use-partitioning"></a>

您可以使用分区通过限制在任何给定时间必须访问的数据量来减少节流。通过对特定列中的数据进行分区，您可以将请求均匀地分配到多个对象，并减少单一对象的请求数量。可通过减少扫描的数据量提高查询性能并降低成本。

创建表时，您可以定义分区，来充当虚拟列。要在 `CREATE TABLE` 语句中创建包含分区的表，可使用 `PARTITIONED BY (column_name data_type)` 子句定义用于对数据进行分区的键。

要限制查询扫描的分区，可以在查询的 `WHERE` 子句中将其指定为谓词。因此，经常用作筛选条件的列是用于分区的理想候选项。常见做法是根据时间间隔对数据进行分区，这可能会导致多层分区方案。

请注意，分区也有成本。当您增加表中的分区数时，检索和处理分区元数据所需的时间也会增加。因此，过度分区可能会抵消以更明智的方式进行分区带来的好处。如果您的数据严重偏向于一个分区值，并且大多数查询都使用该值，则可能会产生额外开销。

有关在 Athena 中进行分区的更多信息，请参阅 [什么是分区？](ctas-partitioning-and-bucketing-what-is-partitioning.md)。

## 对数据进行分桶
<a name="performance-tuning-s3-throttling-bucket-your-data"></a>

对数据进行分区的另一种方法是对单一分区中的数据进行分桶。进行分桶时，可指定包含要分组到一起的行的一列或多列。然后，将这些行放入多个存储桶中。这样，只需查询必须读取的存储桶即可，从而减少必须扫描的数据行数。

在选择要用于分桶的列时，选择具有高基数（即具有许多不同值）、分布均匀且经常用于筛选数据的列。例如，ID 列等主键就是用于分桶的理想列。

有关在 Athena 中分桶的更多信息，请参阅 [什么是分桶？](ctas-partitioning-and-bucketing-what-is-bucketing.md)。

## 使用 AWS Glue 分区索引
<a name="performance-tuning-s3-throttling-use-aws-glue-partition-indexes"></a>

您可以使用 AWS Glue 分区索引根据一个或多个分区值对表中的数据进行组织。AWS Glue 分区索引可以减少数据传输次数、数据处理量和查询处理时间。

AWS Glue 分区索引是一个元数据文件，其中包含有关表中分区的信息，包括分区键及其值。分区索引存储在 Amazon S3 存储桶中，并在向表中添加新分区时由 AWS Glue 自动更新。

当存在 AWS Glue 分区索引时，查询会尝试获取一部分的分区，而不是加载表中的所有分区。将仅对与查询有关的这部分数据运行查询。

在 AWS Glue 中创建表时，可以基于表中定义的任意分区键组合创建分区索引。在表中创建了一个或多个分区索引后，必须向表中添加用于启用分区筛选的属性。然后，您可以从 Athena 查询表。

有关在 AWS Glue 中创建分区索引的信息，请参阅《AWS Glue 开发人员指南**》中的[在 AWS Glue 中使用分区索引](https://docs.aws.amazon.com/glue/latest/dg/partition-indexes.html)。有关添加表属性以启用分区筛选的信息，请参阅 [使用 AWS Glue 分区索引和筛选来优化查询](glue-best-practices-partition-index.md)。

## 使用数据压缩和文件拆分
<a name="performance-tuning-s3-throttling-use-data-compression-and-file-splitting"></a>

如果文件大小理想或者可以按逻辑组对其进行拆分，则数据压缩可以显著加快查询速度。通常，较高的压缩比需要更多的 CPU 周期才能压缩和解压缩数据。对于 Athena，建议使用 Apache Parquet 或 Apache ORC，以默认压缩数据。有关 Athena 中数据压缩的信息，请参阅 [在 Athena 中使用压缩](compression-formats.md)。

可通过拆分文件允许 Athena 将读取单个文件的任务分配给多个读取器，从而提高并行度。如果单个文件不可拆分，则只有一个读取器可以读取该文件，而其他读取器处于空闲状态。Apache Parquet 和 Apache ORC 也支持可拆分文件。

## 使用经过优化的列式数据存储
<a name="performance-tuning-s3-throttling-use-optimized-columnar-data-stores"></a>

如果将数据转换为列式格式，则会显著提高 Athena 查询性能。生成列式文件时，要考虑的一种优化方法是根据分区键对数据进行排序。

Apache Parquet 和 Apache ORC 是常用的开源列式数据存储。有关将现有 Amazon S3 数据来源转换为其中一种格式的信息，请参阅 [转换为列式格式](columnar-storage.md#convert-to-columnar)。

### 使用较大的 Parquet 块大小或 ORC 条带大小
<a name="performance-tuning-s3-throttling-use-a-larger-parquet-block-size-or-orc-stripe-size"></a>

Parquet 和 ORC 具有诸多数据存储参数，您可以调整这些参数以进行优化。在 Parquet 中，您可以针对块大小进行优化。在 ORC 中，您可以针对条带大小进行优化。数据块或条带越大，可在其中存储的行越多。默认情况下，Parquet 块大小为 128MB，ORC 条带大小为 64MB。

如果 ORC 条带小于 8MB（`hive.orc.max_buffer_size` 的默认值），Athena 会读取整个 ORC 条带。这是 Athena 在列选择性和针对较小条带的每秒输入 / 输出操作之间做出的权衡。

如果表的列数非常多，则较小的数据块或条带大小可能会导致扫描的数据量超出必要范围。在此类情况下，较大的块大小可能更高效。

### 使用 ORC 处理复杂类型
<a name="performance-tuning-s3-throttling-use-orc-for-complex-types"></a>

目前，当您查询在 Parquet 中存储的具有复杂数据类型（例如，`array`、`map` 或 `struct`）的列时，Athena 将读取整行数据，而不是有选择性地仅读取指定列。这是 Athena 中的已知问题。要解决该问题，考虑使用 ORC。

### 选择压缩算法
<a name="performance-tuning-s3-throttling-choose-a-compression-algorithm"></a>

可配置的另一个参数是数据块的压缩算法。有关 Athena 中 Parquet 和 ORC 支持的压缩算法的信息，请参阅 [Athena 压缩支持](https://docs.aws.amazon.com/athena/latest/ug/compression-formats.html)。

有关优化 Athena 列式存储格式的更多信息，请参阅 AWS 大数据博客文章 [Amazon Athena 的十大性能调整技巧](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/)中的“优化列式数据存储生成”一节。

## 使用 Iceberg 表
<a name="performance-tuning-s3-throttling-use-iceberg-tables"></a>

Apache Iceberg 是一种适用于超大型分析数据集的开放表格式，专为优化 Amazon S3 使用而设计。可使用 Iceberg 表帮助减少 Amazon S3 节流。

Iceberg 表具有以下优势：
+ 可基于一列或多列对 Iceberg 表进行分区。这将优化数据访问并减少查询必须扫描的数据量。
+ 由于 Iceberg 对象存储模式可优化 Iceberg 表以与 Amazon S3 配合使用，因此它可以处理大量数据和繁重的查询工作负载。
+ 对象存储模式下的 Iceberg 表具有可扩展性、容错性和耐用性，这有助于减少节流。
+ ACID 事务支持意味着多个用户可以原子方式添加和删除 Amazon S3 对象。

有关 Apache Iceberg 的更多信息，请参阅 [Apache Iceberg](https://iceberg.apache.org/)。有关在 Athena 中使用 Apache Iceberg 表的更多信息，请参阅[使用 Iceberg 表](https://docs.aws.amazon.com/athena/latest/ug/querying-iceberg.html)。

# 优化您的查询
<a name="performance-tuning-s3-throttling-optimizing-queries"></a>

使用本节中的建议优化 Athena SQL 查询。

## 在 ORDER BY 子句中使用 LIMIT
<a name="performance-tuning-s3-throttling-use-limit-with-the-order-by-clause"></a>

`ORDER BY` 子句按排序顺序返回数据。这要求 Athena 将所有数据行发送到单一 Worker 节点，然后对这些行进行排序。此类查询可能会运行很长时间，甚至会失败。

为了提高查询效率，查看前或后 *N* 个值，然后还要使用 `LIMIT` 子句。这将显著降低排序成本，因为会将排序和限制推送到各个 Worker 节点而不是单一 Worker。

## 优化 JOIN 子句
<a name="performance-tuning-s3-throttling-optimize-join-clauses"></a>

当您联接两个表时，Athena 会将右侧的表分配给 Worker 节点，然后流式处理左侧的表以执行联接。

因此，在联接的左侧指定较大的表，在联接的右侧指定较小的表。这样可减少 Athena 所用的内存并降低查询运行延迟。

同时注意以下几点：
+ 使用多个 `JOIN` 命令时，按从大到小顺序指定表。
+ 除非查询需要，否则避免使用交叉联接。

## 优化 GROUP BY 子句
<a name="performance-tuning-s3-throttling-optimize-group-by-clauses"></a>

`GROUP BY` 运算符根据 `GROUP BY` 列将行分配给 Worker 节点。这些列将在内存中引用，并在载入行时对值进行比较。当 `GROUP BY` 列匹配时，这些值会聚合在一起。考虑到此过程的工作方式，建议按基数从高到低对列进行排序。

## 使用数字代替字符串
<a name="performance-tuning-s3-throttling-use-numbers-instead-of-strings"></a>

由于与字符串相比，数字所需的内存更少且处理速度更快，因此尽可能使用数字代替字符串。

## 限制列数
<a name="performance-tuning-s3-throttling-limit-the-number-of-columns"></a>

要减少存储数据所需的总内存量，限制在 `SELECT` 语句中指定的列数。

## 使用正则表达式代替 LIKE
<a name="performance-tuning-s3-throttling-use-regular-expressions-instead-of-like"></a>

在大型字符串中包含 `LIKE '%string%'` 等子句的查询的计算量可能非常大。在字符串列中筛选多个值时，改用 [regexp\$1like()](https://trino.io/docs/current/functions/regexp.html#regexp_like) 函数和正则表达式。这在您比较一长串值时特别有用。

## 使用 LIMIT 子句
<a name="performance-tuning-s3-throttling-use-the-limit-clause"></a>

在运行查询时，使用 `LIMIT` 子句仅返回所需的列，而不是选择所有列。这减小了通过查询执行管道处理的数据集的大小。当查询包含大量基于字符串的列的表时，建议使用 `LIMIT` 子句。当您对任何查询执行多个联接或聚合时，也建议使用 `LIMIT` 子句。

# 其他资源
<a name="performance-tuning-additional-resources"></a>

有关 Athena 中性能优化的更多信息，请参考以下资源：
+ AWS 大数据博客文章：[Amazon Athena 的十大性能优化技巧](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/)。
+ AWS 大数据博客文章：*AWS Big Data Blog* 中的 [Run queries 3x faster with up to 70% cost savings on the latest Amazon Athena engine](https://aws.amazon.com/blogs/big-data/run-queries-3x-faster-with-up-to-70-cost-savings-on-the-latest-amazon-athena-engine/)。
+ AWS 大数据博客文章：[在 Amazon Athena 中使用谓词下推改善联合查询](https://aws.amazon.com/blogs/big-data/improve-federated-queries-with-predicate-pushdown-in-amazon-athena/)。
+ 《Amazon Simple Storage Service 用户指南》：[Best practices design patterns: optimizing Amazon S3 performance](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html)。
+ [AWS 大数据博客中的其他 Athena 相关贴文](https://aws.amazon.com/blogs/big-data/tag/amazon-athena/)。
+ 使用 [Amazon Athena](https://repost.aws/tags/TA78iVOM7gR62_QqDe2-CmiA/amazon-athena) 标签在 **AWS re:Post** 上提问。
+ 在 [AWS 知识中心中查询 Athena 主题](https://aws.amazon.com/premiumsupport/knowledge-center/#Amazon_Athena)。
+ 联系 AWS 支持 (在 AWS 管理控制台 中，单击 **Support**(支持)、**Support Center**(支持中心))

# 在 Athena 中使用压缩
<a name="compression-formats"></a>

Athena 支持多种用于读取和写入数据的压缩格式，例如从使用多种压缩格式的表中进行读取。例如，当某些 Parquet 文件使用 Snappy 压缩而其他 Parquet 文件使用 GZIP 压缩时，Athena 可以成功读取使用 Parquet 文件格式的表中的数据。同样的原则适用于 ORC、文本文件和 JSON 存储格式。

## 支持的压缩格式
<a name="compression-support-formats"></a>

Athena 支持以下压缩格式：
+ **BZIP2** – 使用 Burrows-Wheeler 算法的格式。
+ **DEFLATE** – 基于 [LZSS](https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Storer%E2%80%93Szymanski) 和 [Huffman 编码](https://en.wikipedia.org/wiki/Huffman_coding)的压缩算法。[Deflate](https://en.wikipedia.org/wiki/Deflate) 仅与 Avro 文件格式相关。
+ **GZIP** – 基于 Deflate 的压缩算法。对于 Athena 引擎版本 2 和 3 中的 Hive 表，以及 Athena 引擎版本 2 中的 Iceberg 表，GZIP 是 Parquet 和文本文件存储格式文件的默认写入压缩格式。不支持 `tar.gz` 格式的文件。
+ **LZ4** – 属于 Lempel-Ziv 77 (LZ7) 系列，并且也侧重于压缩和解压缩速度，而非对数据的最大限度压缩。LZ4 具有以下成帧格式：
  + **LZ4 Raw/Unframed** – LZ4 数据块压缩格式的标准无帧实现。有关更多信息，请参阅 GitHub 上的 [LZ4 数据块格式说明](https://github.com/lz4/lz4/blob/dev/doc/lz4_Block_format.md)。
  + **LZ4 Framed** – 常见的 LZ4 成帧实现。有关更多信息，请参阅 GitHub 上的 [LZ4 帧格式说明](https://github.com/lz4/lz4/blob/dev/doc/lz4_Frame_format.md)。
  + **LZ4 Hadoop-Compatible** – LZ4 的 Apache Hadoop 实现。此实现使用 [BlockCompressorStream.java](https://github.com/apache/hadoop/blob/f67237cbe7bc48a1b9088e990800b37529f1db2a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/compress/BlockCompressorStream.java) 类封装 LZ4 压缩。
+ **LZO** – 使用 Lempel–Ziv–Oberhumer 算法的格式，该算法侧重于高速压缩和解压缩，而非对数据的最大限度压缩。LZO 具有两个实现：
  + **Standard LZO** – 有关更多信息，请参阅 Oberhumer 网站上的 LZO [摘要](http://www.oberhumer.com/opensource/lzo/#abstract)。
  + **LZO Hadoop-Compatible** – 此实现使用 [BlockCompressorStream.java](https://github.com/apache/hadoop/blob/f67237cbe7bc48a1b9088e990800b37529f1db2a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/compress/BlockCompressorStream.java) 类封装 LZO 算法。
+ **SNAPPY** – 属于 Lempel-Ziv 77 (LZ7) 系列的压缩算法。Snappy 侧重于高速压缩和解压速度，而非对数据的最大限度压缩。
+ **ZLIB** – 基于 Deflate，ZLIB 是 ORC 数据存储格式文件的默认写入压缩格式。有关更多信息，请参阅 GitHub 上的 [zlib](https://github.com/madler/zlib) 页面。
+  **ZSTD** – [Zstandard 实时数据压缩算法](http://facebook.github.io/zstd/)是一种具有高压缩率的快速压缩算法。Zstandard（ZSTD）库作为使用 BSD 许可证的开源软件提供。ZSTD 是 Iceberg 表的默认压缩格式。在写入 ZSTD 压缩数据时，Athena 默认使用 ZSTD 压缩级别 3。有关在 Athena 中使用 ZSTD 压缩级别的更多信息，请参阅 [使用 ZSTD 压缩级别](compression-support-zstd-levels.md)。

**注意**  
Athena 不支持写入以 LZ4 或 LZO 格式压缩的 Parquet 文件。我们支持读取这些压缩格式。

## 指定压缩格式
<a name="compression-support-specifying-compression-formats"></a>

写入 CREATE TABLE 或 CTAS 语句时，您可以指定压缩属性，该属性可指定 Athena 写入这些表时要使用的压缩类型。
+ 对于 CTAS，请参阅 [CTAS 表属性](create-table-as.md#ctas-table-properties)。有关示例，请参阅 [CTAS 查询的示例](ctas-examples.md)。
+ 对于 CREATE TABLE，请参阅 [ALTER TABLE SET TBLPROPERTIES](alter-table-set-tblproperties.md) 以获取压缩表属性列表。

## 指定无压缩
<a name="compression-support-specifying-no-compression"></a>

CREATE TABLE 语句支持写入未压缩的文件。要写入未压缩的文件，请使用以下语法：
+ CREATE TABLE（文本文件或 JSON）– 在 `TBLPROPERTIES` 中，请指定 `write.compression = NONE`。
+ CREATE TABLE (Parquet) – 在 `TBLPROPERTIES` 中，请指定 `parquet.compression = UNCOMPRESSED`。
+ CREATE TABLE (ORC) – 在 `TBLPROPERTIES` 中，请指定 `orc.compress = NONE`。

## 注释和资源
<a name="compression-support-notes-and-resources"></a>
+ 目前，Athena 无法识别大写文件扩展名，例如 `.GZ` 或 `.BZIP2`。避免使用包含大写文件扩展名的数据集，或将数据文件扩展名重命名为小写。
+ 对于 CSV、TSV 和 JSON 格式的数据，Athena 根据文件扩展名确定压缩类型。如果不存在文件扩展名，则 Athena 将数据视为未压缩的纯文本。如果您的数据已压缩，请确保文件名包含压缩扩展名，例如 `gz`。
+ 不支持 ZIP 文件格式。
+ 对于从 Athena 查询 Amazon Data Firehose 日志，支持的格式包括 GZIP 压缩文件或采用 SNAPPY 压缩的 ORC 文件。
+ 有关使用压缩的更多信息，请参阅 AWS 大数据博客文章 [Top 10 performance tuning tips for Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/)（Amazon Athena 的 10 大性能优化技巧）中的第 3 部分（“压缩和拆分文件”）。

**Topics**
+ [指定压缩格式](#compression-support-specifying-compression-formats)
+ [指定无压缩](#compression-support-specifying-no-compression)
+ [注释和资源](#compression-support-notes-and-resources)
+ [Hive 表压缩](compression-support-hive.md)
+ [Iceberg 表压缩](compression-support-iceberg.md)
+ [ZSTD 压缩级别](compression-support-zstd-levels.md)

# 使用 Hive 表压缩
<a name="compression-support-hive"></a>

Athena 中 Hive 表的压缩选项因引擎版本和文件格式而异。

## Athena 引擎版本 3 中的 Hive 压缩支持
<a name="compression-support-hive-v3"></a>

下表总结了对于 Apache Hive 存储文件格式，Athena 引擎版本 3 中支持的压缩格式。文本文件格式包括 TSV、CSV、JSON 和用于文本的自定义 SerDes。除非另有说明，否则单元格中的“是”或“否”同样适用于读取和写入操作。就本表而言，CREATE TABLE、CTAS 和 INSERT INTO 视为写入操作。有关在 Athena 中使用 ZSTD 压缩级别的更多信息，请参阅 [使用 ZSTD 压缩级别](compression-support-zstd-levels.md)。


****  

|  | Avro | Ion | ORC | Parquet | 文本文件 | 
| --- | --- | --- | --- | --- | --- | 
| BZIP2 | 支持 | 是 | 否 | 否 | 是 | 
| DEFLATE | 是 | 否 | 否 | 否 | 否 | 
| GZIP | 否 | 是 | 否 | 是 | 是 | 
| LZ4 | 否 | 是 | 是 |  写入 – 否 读取 – 是  | 是 | 
| LZO | 否 |  写入 – 否 读取 – 是  | 否 |  写入 – 否 读取 – 是  |  写入 – 否 读取 – 是  | 
| SNAPPY | 支持 | 是 | 是 | 是 | 是 | 
| ZLIB | 否 | 否 | 是 | 否 | 否 | 
| ZSTD | 支持 | 是 | 是 | 是 | 是 | 
| NONE | 支持 | 是 | 是 | 是 | 是 | 

# 使用 Iceberg 表压缩
<a name="compression-support-iceberg"></a>

Athena 中 Iceberg 表的压缩选项因引擎版本和文件格式而异。

## Athena 引擎版本 3 中的 Iceberg 压缩支持
<a name="compression-support-iceberg-v3"></a>

下表总结了对于 Apache Iceberg 存储文件格式，Athena 引擎版本 3 中支持的压缩格式。除非另有说明，否则单元格中的“是”或“否”同样适用于读取和写入操作。就本表而言，CREATE TABLE、CTAS 和 INSERT INTO 视为写入操作。在 Athena 引擎版本 3 中，适用于 Iceberg 的默认存储格式为 Parquet。在 Athena 引擎版本 3 中，适用于 Iceberg 的默认压缩格式为 ZSTD。有关在 Athena 中使用 ZSTD 压缩级别的更多信息，请参阅 [使用 ZSTD 压缩级别](compression-support-zstd-levels.md)。


****  

|  | Avro | ORC | Parquet（默认） | 
| --- | --- | --- | --- | 
| BZIP2 | 否 | 否 | 否 | 
| GZIP | 是 | 否 | 是 | 
| LZ4 | 否 | 是 | 否 | 
| SNAPPY | 支持 | 是 | 是 | 
| ZLIB | 否 | 是 | 否 | 
| ZSTD | 支持 | 是 | 是（默认） | 
| NONE | 是（请指定 None 或 Deflate） | 是 | 是（请指定 None 或 Uncompressed） | 

# 使用 ZSTD 压缩级别
<a name="compression-support-zstd-levels"></a>

[Zstandard 实时数据压缩算法](http://facebook.github.io/zstd/) 是一种具有高压缩比的快速压缩算法。Zstandard（ZSTD）库是一种开源软件，使用 BSD 许可证。Athena 支持读取和写入 ZSTD 压缩的 ORC、Parquet 和文本文件数据。

您可以根据自己的需求，使用 ZSTD 压缩级别来调整压缩比和速度。ZSTD 库支持的压缩级别为 1 到 22。Athena 默认使用的 ZSTD 压缩级别为 3。

通过压缩级别可以在压缩速度和要达到的压缩量之间进行精细平衡控制。压缩级别越低，速度越快，但文件越大。例如，在速度最为重要时，可以使用级别 1；在大小最为重要时，可以使用级别 22。默认设置为级别 3，适用于许多应用场景。使用大于 19 的级别时应当谨慎，因为这将需要更多内存。ZSTD 库还提供负压缩级别，从而扩展压缩速度和压缩比的范围。有关更多信息，请参阅 [Zstandard 压缩 RFC](https://datatracker.ietf.org/doc/html/rfc8478)。

由于提供了多种压缩级别，因此可以充分进行微调优化。但在决定压缩级别时，请务必衡量您的数据量并相应权衡。我们建议使用默认级别 3 或介于 6 到 9 之间的级别，以便合理平衡压缩速度和压缩数据大小。20 及以上的级别应专用于大小最为重要且无需关注压缩速度的场景。

## 注意事项和限制
<a name="compression-support-zstd-levels-considerations-and-limitations"></a>

在 Athena 中使用 ZSTD 压缩级别时，请注意以下几点。
+ 仅 Athena 引擎版本 3 支持 ZSTD `compression_level` 属性。
+ `ALTER TABLE`、`CREATE TABLE`、`CREATE TABLE AS`（CTAS）和 `UNLOAD` 语句支持 ZSTD`compression_level` 属性。
+ `compression_level` 属性是可选的。
+ 仅 ZSTD 压缩支持 `compression_level` 属性。
+ 可能的压缩级别为 1 到 22。
+ 默认压缩级别为 3。

有关 Athena 中的 Apache Hive ZSTD 压缩支持的信息，请参阅 [使用 Hive 表压缩](compression-support-hive.md)。有关 Athena 中的 Apache Iceberg ZSTD 压缩支持的信息，请参阅 [使用 Iceberg 表压缩](compression-support-iceberg.md)。

## 指定 ZSTD 压缩级别
<a name="compression-support-zstd-levels-specifying"></a>

要为 `ALTER TABLE`、`CREATE TABLE`、`CREATE TABLE AS` 和 `UNLOAD` 语句指定 ZSTD 压缩级别，请使用 `compression_level` 属性。要指定 ZSTD 压缩本身，您必须使用该语句的语法所用的单个压缩属性。

### ALTER TABLE SET TBLPROPERTIES
<a name="compression-support-zstd-levels-alter-table"></a>

在 [ALTER TABLE SET TBLPROPERTIES](alter-table-set-tblproperties.md) 语句的 `SET TBLPROPERTIES` 子句中，使用 `'write.compression' = ' ZSTD'` 或 `'parquet.compression' = 'ZSTD'` 指定 ZSTD 压缩。然后使用 `compression_level` 属性指定一个介于 1 到 22 之间的值（例如 '`compression_level' = '5'`）。如果您未指定压缩级别属性，则压缩级别默认为 3。

#### 示例
<a name="compression-support-zstd-levels-alter-table-example"></a>

以下示例将修改表 `existing_table` 以使用 Parquet 文件格式以及 ZSTD 压缩和 ZSTD 压缩级别 4。请注意，在 `TBLPROPERTIES` 子句中，压缩级别值必须以字符串而不是整数形式输入，因此压缩级别值必须以单引号或双引号括起来。

```
ALTER TABLE existing_table 
SET TBLPROPERTIES ('parquet.compression' = 'ZSTD', 'compression_level' = '4')
```

### CREATE TABLE
<a name="compression-support-zstd-levels-create-table"></a>

在 [CREATE TABLE](create-table.md) 语句的 `TBLPROPERTIES` 子句中，指定 '`write.compression' = 'ZSTD'` 或 `'parquet.compression' = 'ZSTD'`，然后使用 `compression_level = compression_level` 并指定一个介于 1 到 22 之间的值作为字符串。如果未指定 `compression_level` 属性，则默认压缩级别为 3。

#### 示例
<a name="compression-support-zstd-levels-create-table-example"></a>

以下示例将以 Parquet 文件格式创建一个表，并使用 ZSTD 压缩和 ZSTD 压缩级别 4。

```
CREATE EXTERNAL TABLE new_table ( 
  `col0` string COMMENT '', 
  `col1` string COMMENT '' 
) 
STORED AS PARQUET 
LOCATION 's3://amzn-s3-demo-bucket/' 
TBLPROPERTIES ('write.compression' = 'ZSTD', 'compression_level' = '4')
```

### CREATE TABLE AS (CTAS)
<a name="compression-support-zstd-levels-ctas"></a>

在 [CREATE TABLE AS](create-table-as.md) 语句的 `WITH` 子句中，指定 `write_compression = 'ZSTD'` 或 `parquet_compression = 'ZSTD'`，然后使用 `compression_level = compression_level` 并指定一个介于 1 到 22 之间的值作为整数。如果未指定 `compression_level` 属性，则默认压缩级别为 3。

#### 示例
<a name="compression-support-zstd-levels-ctas-example"></a>

以下 CTAS 示例将指定使用 Parquet 文件格式以及 ZSTD 压缩和 ZSTD 压缩级别 4。请注意，在 `WITH` 子句中，压缩级别的值必须指定为整数，而不是字符串。

```
CREATE TABLE new_table  
WITH ( format = 'PARQUET', write_compression = 'ZSTD', compression_level = 4)  
AS SELECT * FROM old_table
```

### UNLOAD
<a name="compression-support-zstd-levels-unload"></a>

在 [UNLOAD](unload.md) 语句的 `WITH` 子句中，指定 `compression = 'ZSTD'`，然后使用 `compression_level = compression_level` 并指定一个介于 1 到 22 之间的值作为整数。如果未指定 `compression_level` 属性，则默认压缩级别为 3。

#### 示例
<a name="compression-support-zstd-levels-unload-example"></a>

以下示例将使用 Parquet 文件格式、ZSTD 压缩和 ZSTD 压缩级别 4 将查询结果卸载到指定位置。

```
UNLOAD (SELECT * FROM old_table) 
TO 's3://amzn-s3-demo-bucket/' 
WITH (format = 'PARQUET', compression = 'ZSTD', compression_level = 4)
```

# 标记 Athena 资源
<a name="tags"></a>

标签包含您定义的一个键和一个值。您在标记 Athena 资源时，将为该资源分配自定义元数据。您可以使用标签按照不同方式（例如按用途、所有者或环境）对 AWS 资源进行分类。在 Athena 中，工作组、数据目录和容量预留等资源是可标记的资源。例如，您可以在账户中为工作组创建一组标签，以帮助您跟踪工作组所有者，或按用途识别工作组。如果您还在 Billing and Cost Management（账单和成本管理）控制台中启用标签作为成本分配标签，则与运行查询相关的费用将显示在“成本和使用情况报告”中，并带有该成本分配标签。我们建议您使用 AWS [标记最佳实践](https://docs.aws.amazon.com/whitepapers/latest/tagging-best-practices/tagging-best-practices.html) 来创建一组一致的标签，以满足您组织的要求。

您可以通过 Athena 控制台或 API 操作来使用标签。

**Topics**
+ [标签基本知识](#tag-basics)
+ [标签限制](#tag-restrictions)
+ [使用工作组的标签](tags-console.md)
+ [使用 API 和 AWS CLI 标签操作](tags-operations.md)
+ [使用基于标签的 IAM 访问控制策略](tags-access-control.md)

## 标签基本知识
<a name="tag-basics"></a>

标签是为 Athena 资源分配的标记。每个标签都包含定义的一个键和一个可选值。

标签可让您按不同方式对 AWS 资源进行分类。例如，您可以为账户的工作组定义一组标签，以帮助您跟踪每个工作组所有者或用途。

您可以在创建新的 Athena 工作组或数据目录时添加标签，也可以在其中添加、编辑或删除标签。您可以在控制台中编辑标签。要使用 API 操作编辑标签，请删除旧标签并添加新标签。如果删除资源，资源的所有标签也会被删除。

Athena 不会自动向您的资源分配标签。您可以修改标签的密钥和值，还可以随时删除资源的标签。您可以将标签的值设为空的字符串，但是不能将其设为空值。请不要将重复的标签键添加到同一资源中。如果这样操作，Athena 会发布一条错误消息。如果通过 **TagResource** 操作用现有标签键标记资源，则新的标签值将覆盖旧值。

在 IAM 中，您可以控制 Amazon Web Services 账户中的哪些用户有权创建、编辑、删除或列出标签。有关更多信息，请参阅 [使用基于标签的 IAM 访问控制策略](tags-access-control.md)。

有关 Amazon Athena 标记操作的完整列表，请参阅 [Amazon Athena API 参考](https://docs.aws.amazon.com/athena/latest/APIReference/)中的 API 操作名称。

您可以使用标签记账。有关更多信息，请参阅《AWS 账单与成本管理 用户指南**》中的 [使用账单标签](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/custom-tags.html)。

有关更多信息，请参阅 [标签限制](#tag-restrictions)。

## 标签限制
<a name="tag-restrictions"></a>

标签具有以下限制：
+ 在 Athena 中，您可以标记工作组、数据目录和容量预留。但不能标记查询。
+ 每个资源的最大标签数是 50。要不超出限制，请检查并删除未使用的标签。
+ 对于每个资源，每个标签键都必须是唯一的，每个标签键只能有一个值。请不要同时将重复的标签键添加到同一资源中。如果这样操作，Athena 会发布一条错误消息。如果在单独的 `TagResource` 操作中使用现有标签键标记工作组，则新的标签值将覆盖旧值。
+ 标签键长度为 1-128 个 Unicode 字符（UTF-8 格式）。
+ 标签值长度为 0-256 个 Unicode 字符（UTF-8 格式）。

  标记操作（如添加、编辑、删除或列出标签），需要您为工作组资源指定一个 ARN。
+ Athena 允许使用 UTF-8 格式的字母、数字和空格，以及以下字符：\$1 - = . \$1 : / @。
+ 标签键和值区分大小写。
+ 标记键中的 `"aws:"` 前缀将保留以供 AWS 使用。不能编辑或删除带此前缀的标签键。具有此前缀的标签不计入每个资源的标签数限制。
+ 您分配的标签仅可用于您的 Amazon Web Services 账户。

# 使用工作组的标签
<a name="tags-console"></a>

通过 Athena 控制台，您可以查看您账户中每个工作组所使用的标签。您只能按工作组查看标签。您还可以通过 Athena 控制台，每次在一个工作组中应用、编辑或删除标签。

您可以使用创建的标签搜索工作组。

**Topics**
+ [显示单个工作组的标签](#tags-display)
+ [对单个工作组添加和删除标签](#tags-add-delete)

## 显示单个工作组的标签
<a name="tags-display"></a>

**在 Athena 控制台中显示单个工作组的标签**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 如果控制台导航窗格不可见，请选择左侧的扩展菜单。  
![\[选择扩展菜单。\]](http://docs.aws.amazon.com/zh_cn/athena/latest/ug/images/nav-pane-expansion.png)

1. 在导航菜单上，选择 **Workgroups**（工作组），然后选择您希望使用的工作组。

1. 请执行以下操作之一：
   + 选择**标签**选项卡。如果标签列表太长，请使用搜索框。
   + 选择 **Edit**（编辑），然后向下滚动到 **Tags**（标签）部分。

## 对单个工作组添加和删除标签
<a name="tags-add-delete"></a>

您可以从 **Workgroups (工作组)** 选项卡直接管理单个工作组的标签。

**注意**  
如果您希望用户在控制台中创建工作组时添加标签，或者在使用 **CreateWorkGroup** 操作时传入标签，请确保向用户授予 IAM 权限以执行 **TagResource** 和 **CreateWorkGroup** 操作。

**在创建新工作组时添加标签**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 在导航菜单上，选择 **Workgroups**（工作组）。

1. 选择 **Create workgroup**（创建工作组）并根据需要填入值。有关详细步骤，请参阅[创建工作组](creating-workgroups.md)。

1. 在 **Tags**（标签）部分，通过指定密钥和值，添加一个或多个标签。请勿同时将重复的标签键添加到同一个工作组。如果这样操作，Athena 会发布一条错误消息。有关更多信息，请参阅 [标签限制](tags.md#tag-restrictions)。

1. 完成后，选择 **Create workgroup**（创建工作组）。

**对现有工作组添加或编辑标签**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 在导航窗格中，选择 **Workgroups**（工作组）。

1. 选择您想要修改的工作组。

1. 请执行以下操作之一：
   + 选择**标签**选项卡，然后选择**管理标签**。
   + 选择 **Edit**（编辑），然后向下滚动到 **Tags**（标签）部分。

1. 为每个标签指定密钥和值。有关更多信息，请参阅 [标签限制](tags.md#tag-restrictions)。

1. 选择 **Save**。

**删除单个工作组的标签**

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 在导航窗格中，选择 **Workgroups**（工作组）。

1. 选择您想要修改的工作组。

1. 请执行以下操作之一：
   + 选择**标签**选项卡，然后选择**管理标签**。
   + 选择 **Edit**（编辑），然后向下滚动到 **Tags**（标签）部分。

1. 在标签列表中，为要删除的标签选择 **Remove**（删除），然后选择 **Save**（保存）。

# 使用 API 和 AWS CLI 标签操作
<a name="tags-operations"></a>

使用以下标签操作在资源中添加、删除或列出标签。


****  

| API | CLI | 操作描述 | 
| --- | --- | --- | 
| TagResource | tag-resource | 在具有指定 ARN 的资源上添加或覆盖一个或多个标签。 | 
| UntagResource | untag-resource | 从具有指定 ARN 的资源中删除一个或多个标签。 | 
| ListTagsForResource | list‑tags‑for‑resource | 列出具有指定 ARN 的资源的一个或多个标签。 | 

**在创建资源时添加标签**  
要在创建工作组或数据目录时添加标签，请将 `tags` 参数与 `CreateWorkGroup` 或 `CreateDataCatalog` API 操作结合使用，或者将该参数与 AWS CLI `create-work-group` 或 `create-data-catalog` 命令结合使用。

## 使用 API 操作管理标签
<a name="tags-operations-examples-java"></a>

以下示例说明如何使用标签 API 操作来管理工作组和数据目录上的标签。这些示例采用的是 Java 编程语言。

### 示例：TagResource
<a name="tags-operations-examples-java-tag-resource"></a>

以下示例将两个标签添加到工作组 `workgroupA` 中：

```
List<Tag> tags = new ArrayList<>();
tags.add(new Tag().withKey("tagKey1").withValue("tagValue1"));
tags.add(new Tag().withKey("tagKey2").withValue("tagValue2"));

TagResourceRequest request = new TagResourceRequest()
    .withResourceARN("arn:aws:athena:us-east-1:123456789012:workgroup/workgroupA")
    .withTags(tags);

client.tagResource(request);
```

以下示例将两个标签添加到数据目录 `datacatalogA` 中：

```
List<Tag> tags = new ArrayList<>();
tags.add(new Tag().withKey("tagKey1").withValue("tagValue1"));
tags.add(new Tag().withKey("tagKey2").withValue("tagValue2"));

TagResourceRequest request = new TagResourceRequest()
    .withResourceARN("arn:aws:athena:us-east-1:123456789012:datacatalog/datacatalogA")
    .withTags(tags);

client.tagResource(request);
```

**注意**  
请不要将重复的标签键添加到同一资源中。如果这样操作，Athena 会发布一条错误消息。如果在单独的 `TagResource` 操作中使用现有标签键标记工作组，则新的标签值将覆盖旧值。

### 示例：UntagResource
<a name="tags-operations-examples-java-untag-resource"></a>

以下示例从工作组 `workgroupA` 中删除 `tagKey2`：

```
List<String> tagKeys = new ArrayList<>();
tagKeys.add("tagKey2");

UntagResourceRequest request = new UntagResourceRequest()
    .withResourceARN("arn:aws:athena:us-east-1:123456789012:workgroup/workgroupA")
    .withTagKeys(tagKeys);

client.untagResource(request);
```

以下示例从数据目录 `datacatalogA` 中删除 `tagKey2`：

```
List<String> tagKeys = new ArrayList<>();
tagKeys.add("tagKey2");

UntagResourceRequest request = new UntagResourceRequest()
    .withResourceARN("arn:aws:athena:us-east-1:123456789012:datacatalog/datacatalogA")
    .withTagKeys(tagKeys);

client.untagResource(request);
```

### 示例：ListTagsForResource
<a name="tags-operations-examples-java-list-tags-for-resource"></a>

以下示例列出了工作组 `workgroupA` 的标签：

```
ListTagsForResourceRequest request = new ListTagsForResourceRequest()
    .withResourceARN("arn:aws:athena:us-east-1:123456789012:workgroup/workgroupA");

ListTagsForResourceResult result = client.listTagsForResource(request);

List<Tag> resultTags = result.getTags();
```

以下示例列出了数据目录 `datacatalogA` 的标签：

```
ListTagsForResourceRequest request = new ListTagsForResourceRequest()
    .withResourceARN("arn:aws:athena:us-east-1:123456789012:datacatalog/datacatalogA");

ListTagsForResourceResult result = client.listTagsForResource(request);

List<Tag> resultTags = result.getTags();
```

## 使用 AWS CLI 管理标签
<a name="tags-operations-examples-cli"></a>

以下示例说明如何使用 AWS CLI 创建和管理数据目录上的标签。

### 将标签添加到资源：tag-resource
<a name="tags-operations-examples-cli-tag-resource"></a>

`tag-resource` 命令可向指定资源添加一个或多个标签。

**语法**  
`aws athena tag-resource --resource-arn arn:aws:athena:region:account_id:datacatalog/catalog_name --tags Key=string,Value=string Key=string,Value=string`

`--resource-arn` 参数指定要将标签添加到的资源。`--tags` 参数指定要作为标签添加到资源的用空格分隔的键/值对列表。

**Example**  
以下示例将标签添加到 `mydatacatalog` 数据目录中。  

```
aws athena tag-resource --resource-arn arn:aws:athena:us-east-1:111122223333:datacatalog/mydatacatalog --tags Key=Color,Value=Orange Key=Time,Value=Now
```
要显示结果，请使用 `list-tags-for-resource` 命令。  
有关在使用 `create-data-catalog` 命令时添加标签的信息，请参阅 [注册目录：Create-data-catalog](datastores-hive-cli.md#datastores-hive-cli-registering-a-catalog)。

### 列出资源的标签：list-tags-for-resource
<a name="tags-operations-examples-cli-list-tags-for-resource"></a>

`list-tags-for-resource` 命令将列出指定资源的标签。

**语法**  
`aws athena list-tags-for-resource --resource-arn arn:aws:athena:region:account_id:datacatalog/catalog_name`

`--resource-arn` 参数指定将列出其标签的资源。

以下示例列出了 `mydatacatalog` 数据目录的标签。

```
aws athena list-tags-for-resource --resource-arn arn:aws:athena:us-east-1:111122223333:datacatalog/mydatacatalog
```

以下示例结果采用 JSON 格式。

```
{
    "Tags": [
        {
            "Key": "Time",
            "Value": "Now"
        },
        {
            "Key": "Color",
            "Value": "Orange"
        }
    ]
}
```

### 从资源中移除标签：untag-resource
<a name="tags-operations-examples-cli-untag-resource"></a>

`untag-resource` 命令将从指定资源中删除指定的标签键及其关联的值。

**语法**  
`aws athena untag-resource --resource-arn arn:aws:athena:region:account_id:datacatalog/catalog_name --tag-keys key_name [key_name ...]` 

`--resource-arn` 参数指定从中删除标签的资源。`--tag-keys` 参数采用一组用空格分隔的键名称。对于指定的每个键名称，`untag-resource` 命令将同时删除键及其值。

以下示例从 `mydatacatalog` 目录资源中删除 `Color` 和 `Time` 键及其值。

```
aws athena untag-resource --resource-arn arn:aws:athena:us-east-1:111122223333:datacatalog/mydatacatalog --tag-keys Color Time
```

# 使用基于标签的 IAM 访问控制策略
<a name="tags-access-control"></a>

拥有标签后，您可以编写包含 `Condition` 块的 IAM policy，以便基于其标签来控制对资源的访问。本部分包括工作组和数据目录资源的标签策略示例。

## 工作组的标签策略示例
<a name="tag-policy-examples-workgroups"></a>

### 示例：基本标记策略
<a name="tag-policy-examples-workgroups-basic"></a>

以下 IAM policy 允许您运行查询并与名为 `workgroupA` 的工作组的标签进行交互：

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
       {
            "Effect": "Allow",
            "Action": [
                "athena:ListWorkGroups",
                "athena:ListEngineVersions",
                "athena:ListDataCatalogs",
                "athena:ListDatabases",
                "athena:GetDatabase",
                "athena:ListTableMetadata",
                "athena:GetTableMetadata"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "athena:GetWorkGroup",
                "athena:TagResource",
                "athena:UntagResource",
                "athena:ListTagsForResource",
                "athena:StartQueryExecution",
                "athena:GetQueryExecution",
                "athena:BatchGetQueryExecution",
                "athena:ListQueryExecutions",
                "athena:StopQueryExecution",
                "athena:GetQueryResults",
                "athena:GetQueryResultsStream",
                "athena:CreateNamedQuery",
                "athena:GetNamedQuery",
                "athena:BatchGetNamedQuery",
                "athena:ListNamedQueries",
                "athena:DeleteNamedQuery",
                "athena:CreatePreparedStatement",
                "athena:GetPreparedStatement",
                "athena:ListPreparedStatements",
                "athena:UpdatePreparedStatement",
                "athena:DeletePreparedStatement"
            ],
            "Resource": "arn:aws:athena:us-east-1:123456789012:workgroup/workgroupA"
        }
    ]
}
```

------

### 示例：基于标签键和标签值对拒绝对工作组的操作的策略块
<a name="tag-policy-examples-workgroups-basic"></a>

与资源（如工作组）关联的标签称作资源标签。利用资源标签，您可以编写如下所示的策略块，以拒绝对使用键-值对（如 `stack`、`production`）标记的任何工作组执行列出的操作。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Deny",
            "Action": [
                "athena:GetWorkGroup",
                "athena:UpdateWorkGroup",
                "athena:DeleteWorkGroup",
                "athena:TagResource",
                "athena:UntagResource",
                "athena:ListTagsForResource",
                "athena:StartQueryExecution",
                "athena:GetQueryExecution",
                "athena:BatchGetQueryExecution",
                "athena:ListQueryExecutions",
                "athena:StopQueryExecution",
                "athena:GetQueryResults",
                "athena:GetQueryResultsStream",
                "athena:CreateNamedQuery",
                "athena:GetNamedQuery",
                "athena:BatchGetNamedQuery",
                "athena:ListNamedQueries",
                "athena:DeleteNamedQuery",
                "athena:CreatePreparedStatement",
                "athena:GetPreparedStatement",
                "athena:ListPreparedStatements",
                "athena:UpdatePreparedStatement",
                "athena:DeletePreparedStatement"
            ],
            "Resource": "arn:aws:athena:us-east-1:123456789012:workgroup/*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/stack": "production"
                }
            }
        }
    ]
}
```

------

### 示例：限制对指定标签执行标签更改操作请求的策略块
<a name="tag-policy-examples-workgroups-restricted-specific"></a>

作为参数传入将更改标签的操作（例如，带标签的 `TagResource`、`UntagResource` 或 `CreateWorkGroup`）的标签称作请求标签。仅在传递的某个标签的键为 `costcenter` 且值为 `1`、`2` 或 `3` 时，以下示例策略块才允许 `CreateWorkGroup` 操作。

**注意**  
如果要允许 IAM 角色将标签作为 `CreateWorkGroup` 操作的一部分传入，请确保向角色授予执行 `TagResource` 和 `CreateWorkGroup` 操作的权限。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "athena:CreateWorkGroup",
                "athena:TagResource"
            ],
            "Resource": "arn:aws:athena:us-east-1:123456789012:workgroup/*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/costcenter": [
                        "1",
                        "2",
                        "3"
                    ]
                }
            }
        }
    ]
}
```

------

## 数据目录的标签策略示例
<a name="tag-policy-examples-data-catalogs"></a>

### 示例：基本标记策略
<a name="tag-policy-examples-data-catalogs-basic"></a>

以下 IAM policy 允许您与名为 `datacatalogA` 的数据目录的标签进行交互：

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "athena:ListWorkGroups",
                "athena:ListEngineVersions",
                "athena:ListDataCatalogs",
                "athena:ListDatabases",
                "athena:GetDatabase",
                "athena:ListTableMetadata",
                "athena:GetTableMetadata"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "athena:GetWorkGroup",
                "athena:TagResource",
                "athena:UntagResource",
                "athena:ListTagsForResource",
                "athena:StartQueryExecution",
                "athena:GetQueryExecution",
                "athena:BatchGetQueryExecution",
                "athena:ListQueryExecutions",
                "athena:StopQueryExecution",
                "athena:GetQueryResults",
                "athena:GetQueryResultsStream",
                "athena:CreateNamedQuery",
                "athena:GetNamedQuery",
                "athena:BatchGetNamedQuery",
                "athena:ListNamedQueries",
                "athena:DeleteNamedQuery"
            ],
            "Resource": [
                "arn:aws:athena:us-east-1:123456789012:workgroup/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "athena:CreateDataCatalog",
                "athena:GetDataCatalog",
                "athena:UpdateDataCatalog",
                "athena:DeleteDataCatalog",
                "athena:ListDatabases",
                "athena:GetDatabase",
                "athena:ListTableMetadata",
                "athena:GetTableMetadata",
                "athena:TagResource",
                "athena:UntagResource",
                "athena:ListTagsForResource"
            ],
            "Resource": "arn:aws:athena:us-east-1:123456789012:datacatalog/datacatalogA"
        }
    ]
}
```

------

### 示例：基于标签键和标签值对拒绝对数据目录的操作的策略块
<a name="tag-policy-examples-data-catalogs-deny-actions"></a>

您可以使用资源标签编写策略块，以拒绝对使用特定标签键/值对标记的数据目录执行特定操作。以下示例策略拒绝对具有标签键/值对 `stack` `production` 的数据目录执行操作。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Deny",
            "Action": [
                "athena:CreateDataCatalog",
                "athena:GetDataCatalog",
                "athena:UpdateDataCatalog",
                "athena:DeleteDataCatalog",
                "athena:GetDatabase",
                "athena:ListDatabases",
                "athena:GetTableMetadata",
                "athena:ListTableMetadata",
                "athena:StartQueryExecution",
                "athena:TagResource",
                "athena:UntagResource",
                "athena:ListTagsForResource"
            ],
            "Resource": "arn:aws:athena:us-east-1:123456789012:datacatalog/*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/stack": "production"
                }
            }
        }
    ]
}
```

------

### 示例：限制对指定标签执行标签更改操作请求的策略块
<a name="tag-policy-examples-data-catalogs-action-specific-tags"></a>

作为参数传入将更改标签的操作（例如，带标签的 `TagResource`、`UntagResource` 或 `CreateDataCatalog`）的标签称作请求标签。仅在传递的某个标签的键为 `costcenter` 且值为 `1`、`2` 或 `3` 时，以下示例策略块才允许 `CreateDataCatalog` 操作。

**注意**  
如果要允许 IAM 角色将标签作为 `CreateDataCatalog` 操作的一部分传入，请确保向角色授予执行 `TagResource` 和 `CreateDataCatalog` 操作的权限。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "athena:CreateDataCatalog",
                "athena:TagResource"
            ],
            "Resource": "arn:aws:athena:us-east-1:123456789012:datacatalog/*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/costcenter": [
                        "1",
                        "2",
                        "3"
                    ]
                }
            }
        }
    ]
}
```

------

# 服务配额
<a name="service-limits"></a>

**注意**  
Service Quotas 控制台提供有关 Amazon Athena 配额的信息。对于可调整的限额，您可以使用服务限额控制台[请求增加限额](https://console.aws.amazon.com/servicequotas/home?region=us-east-1#!/services/athena/quotas)。有关与 AWS Glue 相关的架构限制，请参阅 [AWS Glue 端点和限额](https://docs.aws.amazon.com/general/latest/gr/glue.html)页面。有关 AWS 服务限额的一般性信息，请参阅 *AWS 一般参考* 中的 [AWS 服务限额](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html)。

## 查询
<a name="service-limits-queries"></a>

您的账户对于 Amazon Athena 具有以下与查询相关的配额。有关详细信息，请参阅 AWS 一般参考 的 [Amazon Athena 端点和限额](https://docs.aws.amazon.com/general/latest/gr/athena.html#amazon-athena-limits)页面。
+ **活跃 DDL 查询** – 活跃 DDL 查询的数量。DDL 查询包括 `CREATE TABLE` 和 `ALTER TABLE ADD PARTITION` 查询。
+ **DDL 查询超时** – DDL 查询在取消之前可以运行的最长时间（以分钟为单位）。
+ **活跃 DML 查询** – 活跃 DML 查询的数量。DML 查询包括 `SELECT`、`CREATE TABLE AS` (CTAS) 和 `INSERT INTO` 查询。具体配额因 AWS 区域而异。
+ **DML 查询超时** – DML 查询在取消之前可以运行的最长时间（以分钟为单位）。您可以申请延长此超时时间，但最长不得超过 240 分钟。

要请求增加限额，您可以使用 [Athena 服务限额](https://console.aws.amazon.com/servicequotas/home?region=us-east-1#!/services/athena/quotas)控制台。

Athena 会根据总体服务负载和传入请求的数量，通过分配资源来处理查询。您的查询可能会在运行之前临时排队。异步进程从队列中获取查询，并在资源可用时立即在物理资源上运行它们，只要您的账户配置允许。

活动 DML 查询和活动 DDL 查询配额包括正在运行的查询和排队的查询。例如，假设活动 DML 配额为 25，而正在运行和排队的查询总数为 26，则查询 26 将导致 TooManyRequestsException 错误。

**注意**  
如果您想直接控制在 Athena 中运行的查询的并发性，则可以使用容量预留。有关更多信息，请参阅 [管理查询处理容量](capacity-management.md)。

### 查询字符串长度
<a name="service-limits-query-string-length"></a>

查询字符串允许的最大长度为 262144 字节，字符串采用 UTF-8 编码。这不是一个可调节的配额。但是，您可以通过将长查询拆分为多个较小的查询来解决此限制。有关更多信息，请参阅 AWS 知识中心中的[如何增加 Athena 中的最大查询字符串长度？](https://aws.amazon.com/premiumsupport/knowledge-center/athena-query-string-length/)。

## 工作组
<a name="service-limits-workgroups"></a>

使用 Athena 工作组时，请记住以下几点：
+ Athena 服务配额在账户中的所有工作组之间共享。
+ 可为您账户中的每个区域创建的工作组的最大数量为 1000。
+ 工作组中的最大预处理语句数为 1000。
+ 每个工作组的最大标签数是 50。有关更多信息，请参阅 [标签限制](tags.md#tag-restrictions)。

## 数据库、表和分区
<a name="service-limits-glue"></a>

Athena 使用 AWS Glue Data Catalog。有关表、数据库和分区的服务配额（例如，每个帐户的数据库或表的最大数量），请参阅 [AWS Glue 端点和配额](https://docs.aws.amazon.com/general/latest/gr/glue.html)。请注意，尽管 Athena 支持查询具有 1 千万个分区的 AWS Glue 表，但 Athena 的单次扫描读取量最多为 1 百万个分区。

## Amazon S3 存储桶
<a name="service-limits-buckets"></a>

使用 Amazon S3 存储桶时，请记住以下几点：
+ Amazon S3 的默认服务配额为每个账户 1 万个存储桶。
+ Athena 需要一个单独的存储桶来记录结果。
+ 您可以请求将配额增加到每个 AWS 账户最高 100 万个 Amazon S3 存储桶。

## 每个账户 API 调用配额
<a name="service-limits-api-calls"></a>

Athena API 规定了每个账户（不是每个查询）的 API 调用数默认配额。有关默认配额的完整列表，请参阅《AWS 一般参考》指南中的 [Service quotas](https://docs.aws.amazon.com/general/latest/gr/athena.html#amazon-athena-limits) 表。

如果您使用这些 API 中的任何一个，并且超出了每秒调用次数的默认配额或您账户中的容量暴增，则 Athena API 会发出类似于以下内容的错误：“ClientError: An error occurred (ThrottlingException) when calling the *<API\$1name>* operation: Rate exceeded. (ClientError：调用操作时发生错误 (ThrottlingException)：超出速率。)” 减少每秒调用次数或此账户的 API 容量暴增。

可以在 [Athena 服务配额控制台](https://console.aws.amazon.com/servicequotas/home?region=us-east-1#!/services/athena/quotas)中更改 Athena 的每账户 API 调用配额。