

# CTAS 查询的注意事项和限制
<a name="ctas-considerations-limitations"></a>

以下章节说明了在 Athena 中使用 `CREATE TABLE AS SELECT`（CTAS）查询时需注意的考虑因素和限制。

## 学习 CTAS 查询语法
<a name="ctas-considerations-limitations-query-syntax"></a>

CTAS 查询语法不同于用于创建表的 `CREATE [EXTERNAL] TABLE` 语法。请参阅[CREATE TABLE AS](create-table-as.md)。

## 视图与 CTAS 查询之间的区别
<a name="ctas-considerations-limitations-queries-vs-views"></a>

CTAS 查询将新数据写入 Amazon S3 中的指定位置。而视图不会写入任何数据。

## 为 CTAS 查询结果指定位置
<a name="ctas-considerations-limitations-location-of-query-results"></a>

如果您的工作组为查询结果位置[覆盖客户端设置](workgroups-settings-override.md)，则 Athena 会在位置 `s3://amzn-s3-demo-bucket/tables/<query-id>/` 创建表。要查看为工作组指定的查询结果位置，请[查看工作组的详细信息](viewing-details-workgroups.md)。

如果您的工作组不覆盖查询结果位置，则可在 CTAS 查询中使用语法 `WITH (external_location ='s3://amzn-s3-demo-bucket/')` 来指定 CTAS 查询结果的存储位置。

**注意**  
`external_location` 属性必须指定一个空位置。CTAS 查询检查存储桶中的路径位置（前缀）是否为空，如果该位置中已有数据，永远不会覆盖这些数据。要再次使用相同的位置，请删除存储桶中键前缀位置的数据。

如果省略 `external_location` 语法并且未使用工作组设置，则 Athena 会使用查询结果位置的[客户端设置](query-results-specify-location-console.md)，并在位置 `s3://amzn-s3-demo-bucket/<Unsaved-or-query-name>/<year>/<month/<date>/tables/<query-id>/` 创建表。

## 查找孤立文件
<a name="ctas-considerations-limitations-locating-orphaned-files"></a>

如果 `CTAS` 或 `INSERT INTO` 语句失败，则失败或取消的查询可能会在目标数据位置留下孤立数据。由于 Athena 在某些情况下不会从目标存储桶中删除查询的数据，因此部分数据可能会包含在后续查询中。

若要查找孤立文件以执行检查或删除操作，您可以使用 Athena 提供的数据清单文件跟踪要写入的文件列表。在极少数情况下，Athena 查询突然失败时，清单文件可能不存在。您可以手动检查目标 S3 位置来查找孤立文件。有关更多信息，请参阅[识别查询输出文件](querying-finding-output-files.md#querying-identifying-output-files)和 [DataManifestLocation](https://docs.aws.amazon.com/athena/latest/APIReference/API_QueryExecutionStatistics.html#athena-Type-QueryExecutionStatistics-DataManifestLocation)。

我们强烈建议使用 Apache Iceberg 来实现表的原子事务。有关更多信息，请参阅 [查询 Apache Iceberg 表](querying-iceberg.md)。

## 请记住，ORDER BY 子句被忽略
<a name="ctas-considerations-limitations-order-by-ignored"></a>

在 CTAS 查询中，Athena 会忽略查询的 `SELECT` 部分中的 `ORDER BY` 子句。

根据 SQL 规范（ISO 9075 第 2 部分），只有直接包含 `ORDER BY` 子句的查询表达式才能保证由查询表达式指定的表的行顺序。在任何情况下，SQL 中的表本质上都是无序的，在子查询子句中实施 `ORDER BY` 会导致查询性能不佳，同时不会生成输出有序。因此，在 Athena CTAS 查询中，无法保证在写入数据时保留 `ORDER BY` 子句指定的顺序。

## 选择一种格式来存储您的查询结果
<a name="ctas-considerations-limitations-formats-for-query-results"></a>

您可以使用 `PARQUET`、`ORC`、`AVRO`、`JSON` 和 `TEXTFILE` 格式存储 CTAS 结果。CTAS `TEXTFILE` 格式不支持多字符分隔符。如果您未指定数据存储格式，默认情况下，CTAS 查询结果以 Parquet 格式存储。

CTAS 查询不需要指定 SerDe 来解释格式转换。请参阅[Example: Writing query results to a different format](ctas-examples.md#ctas-example-format)。

## 考虑压缩格式
<a name="ctas-considerations-limitations-compression-formats"></a>

`GZIP` 压缩用于 JSON 和 TEXTFILE 格式的 CTAS 查询结果。对于 Parquet，您可以使用 `GZIP` 或者 `SNAPPY`，默认为 `GZIP`。对于 ORC，您可以使用 `LZ4`、`SNAPPY`、`ZLIB`，或者 `ZSTD`，默认为 `ZLIB`。有关指定压缩的 CTAS 示例，请参阅 [Example: Specifying data storage and compression formats](ctas-examples.md#ctas-example-compression)。有关 Athena 中压缩的更多信息，请参阅 [在 Athena 中使用压缩](compression-formats.md)。

## 对结果进行分区和分桶
<a name="ctas-considerations-limitations-partition-and-bucket-limits"></a>

您可以对 CTAS 查询的结果数据进行分区和分桶。要指定目标表的属性，在 `WITH` 子句末尾包括分区和分桶谓词。有关更多信息，请参阅[使用分区和分桶](ctas-partitioning-and-bucketing.md)和[Example: Creating bucketed and partitioned tables](ctas-examples.md#ctas-example-bucketed)。

使用 CTAS 创建分区表时，Athena 的写入限制为 100 个分区。有关绕过 100 个分区的限制的信息，请参阅[使用 CTAS 和 INSERT INTO 绕过 100 分区限制](ctas-insert-into.md)。

## 加密您的结果
<a name="ctas-considerations-limitations-encryption"></a>

您可以加密 Amazon S3 中的 CTAS 查询结果，其方法类似于在 Athena 中加密其他查询结果。有关更多信息，请参阅 [加密在 Amazon S3 中存储的 Athena 查询结果](encrypting-query-results-stored-in-s3.md)。

## 预期存储桶所有者设置不适用于 CTAS
<a name="ctas-considerations-limitations-expected-bucket-owner"></a>

对于 CTAS 语句，预期存储桶拥有者设置不适用于 Amazon S3 中的目标表位置。预期存储桶拥有者设置仅适用于您为 Athena 查询结果指定的 Amazon S3 输出位置。有关更多信息，请参阅 [使用 Athena 控制台指定查询结果位置](query-results-specify-location-console.md)。

## 已保留列数据类型
<a name="ctas-considerations-limitations-data-types"></a>

CTAS 查询的列数据类型与为原始查询指定的类型相同。