

# UNLOAD
<a name="unload"></a>

将查询结果从 `SELECT` 语句写为指定的数据格式。`UNLOAD` 支持的格式包括 Apache Parquet、ORC、Apache Avro 和 JSON。CSV 是 Athena `SELECT` 命令支持的唯一输出格式，但您可以使用支持多种输出格式的 `UNLOAD` 命令将 `SELECT` 查询括起来，并将其输出重写为 `UNLOAD` 支持的其中一种格式。

尽管您可以使用 `CREATE TABLE AS`（CTAS）语句以 CSV 以外的格式输出数据，但 CTAS 语句需要在 Athena 中创建表。`UNLOAD` 语句在您想以非 CSV 格式获取 `SELECT` 查询的输出结果，但不需要关联的表时很有用。例如，下游应用程序可能需要将 `SELECT` 查询的结果设置为 JSON 格式，而如果您打算使用 `SELECT` 查询的结果进行其他分析，则相较于 CSV，Parquet 或 ORC 可能会在性能上更有优势。

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

当您在 Athena 中使用 `UNLOAD` 语句时，请记住以下几点：
+ **没有文件的全局排序** – `UNLOAD` 结果将并行写入多个文件。如果 `UNLOAD` 语句中的 `SELECT` 查询指定排序顺序，则每个文件的内容都将按顺序排序，但文件不相对于彼此排序。
+ **孤立数据未删除** – 在出现故障的情况下，Athena 不会尝试删除孤立的数据。这种行为与 CTAS 和 `INSERT INTO` 语句相同。
+ **最大分区** – `UNLOAD` 可以使用的最大分区数为 100。
+ **元数据和清单文件** – Athena 为每个 `UNLOAD` 查询生成元数据文件和数据清单文件。清单跟踪查询写入的文件。这两个文件都会保存到 Amazon S3 中的 Athena 查询结果位置。有关更多信息，请参阅 [识别查询输出文件](querying-finding-output-files.md#querying-identifying-output-files)。
+ **加密** – `UNLOAD` 输出文件将根据用于 Amazon S3 的加密配置进行加密。要设置加密配置以加密 `UNLOAD` 结果，则可以使用 [EncryptionConfiguration API](https://docs.aws.amazon.com/athena/latest/APIReference/API_EncryptionConfiguration.html)。
+ **已准备好语句** – `UNLOAD` 可以与准备好的语句一起使用。有关 Athena 中准备语句的信息，请参阅 [使用参数化查询](querying-with-prepared-statements.md)。
+ **服务配额**：`UNLOAD` 使用 DML 查询配额。有关配额的信息，请参阅 [服务配额](service-limits.md)。
+ **预期存储桶拥有者** – 预期存储桶拥有者设置不适用于在 `UNLOAD` 查询中指定的目标 Amazon S3 位置。预期存储桶拥有者设置仅适用于您为 Athena 查询结果指定的 Amazon S3 输出位置。有关更多信息，请参阅 [使用 Athena 控制台指定查询结果位置](query-results-specify-location-console.md)。

## 语法
<a name="unload-syntax"></a>

`UNLOAD` 语句使用以下语法。

```
UNLOAD (SELECT col_name[, ...] FROM old_table) 
TO 's3://amzn-s3-demo-bucket/my_folder/' 
WITH ( property_name = 'expression' [, ...] )
```

除了写入分区时，`TO` 目标必须在 Amazon S3 中指定一个没有数据的位置。在 `UNLOAD` 查询写入指定的位置前，它会验证存储桶位置是否为空。由于如果位置中已有数据，则 `UNLOAD` 不会向指定的位置写入数据，而 `UNLOAD` 不会覆盖现有数据。要重新使用存储桶位置作为 `UNLOAD` 的目标，请删除存储桶位置中的数据，然后再次运行查询。

请注意，当 `UNLOAD` 写入分区时，此行为会有所不同。如果多次运行具有相同 `SELECT` 语句、相同 `TO` 位置和相同分区的相同 `UNLOAD` 查询，则每个 `UNLOAD` 查询都会在指定的位置和分区将数据卸载到 Amazon S3 中。

### 参数
<a name="unload-parameters"></a>

*property\$1name* 的可能值如下所示。

** format = '*file\$1format*'**  
必需。指定输出的文件格式。*file\$1format* 可能的值为 `ORC`、`PARQUET`、`AVRO`、`JSON` 或 `TEXTFILE`。

** compression = '*compression\$1format*'**  
可选。此选项特定于 ORC 和 Parquet 格式。对于 ORC，默认值为 `zlib`，对于 Parquet，默认为 `gzip`。有关支持的压缩格式的信息，请参阅 [Athena 压缩支持](https://docs.aws.amazon.com/athena/latest/ug/compression-formats.html)。  
此选项不适用于 `AVRO` 格式。Athena 将 `gzip` 用于 `JSON` 和 `TEXTFILE` 格式。

**压缩级别 = *compression\$1level* **  
可选。要用于 ZSTD 压缩的压缩级别。此属性仅适用于 ZSTD 压缩。有关更多信息，请参阅 [使用 ZSTD 压缩级别](compression-support-zstd-levels.md)。

** field\$1delimiter = '*delimiter*'**  
可选。为 CSV、TSV 和其他文本格式文件指定单字符字段分隔符。下面的示例指定了逗号分隔符。  

```
WITH (field_delimiter = ',')
```
目前，不支持多字符字段分隔符。如果您未指定字段分隔符，则会使用八进制字符 `\001` (^A)。

** partitioned\$1by = ARRAY[ *col\$1name*[,…] ] **  
可选。输出进行分区所依据的列的数组列表。  
在 `SELECT` 语句中，确保分区列的名称在列列表中最后列出。

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

下面的示例将 `SELECT` 查询的输出写入了 Amazon S3 位置 `s3://amzn-s3-demo-bucket/unload_test_1/`，使用的是 JSON 格式。

```
UNLOAD (SELECT * FROM old_table) 
TO 's3://amzn-s3-demo-bucket/unload_test_1/' 
WITH (format = 'JSON')
```

下面的示例使用 Snappy 压缩以 Parquet 格式写入了 `SELECT` 查询的输出。

```
UNLOAD (SELECT * FROM old_table) 
TO 's3://amzn-s3-demo-bucket/' 
WITH (format = 'PARQUET',compression = 'SNAPPY')
```

以下示例以文本格式写入四列，按最后一列对输出进行分区。

```
UNLOAD (SELECT name1, address1, comment1, key1 FROM table1) 
TO 's3://amzn-s3-demo-bucket/ partitioned/' 
WITH (format = 'TEXTFILE', partitioned_by = ARRAY['key1'])
```

以下示例将使用 Parquet 文件格式、ZSTD 压缩和 ZSTD 压缩级别 4 将查询结果卸载到指定位置。

```
UNLOAD (SELECT * FROM old_table) 
TO 's3://amzn-s3-demo-bucket/' 
WITH (format = 'PARQUET', compression = 'ZSTD', compression_level = 4)
```

## 其他资源
<a name="unload-additional-resources"></a>
+ *AWS 大数据博客*中的[使用 Amazon Athena UNLOAD 功能简化您的 ETL 和 ML 管道](https://aws.amazon.com/blogs/big-data/simplify-your-etl-and-ml-pipelines-using-the-amazon-athena-unload-feature/)。