

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 将 S3 Select 与 Spark 结合使用以提高查询性能
<a name="emr-spark-s3select"></a>

**重要**  
不再向新客户提供 Amazon S3 Select。Amazon S3 Select 的现有客户可以像往常一样继续使用该功能。[了解详情](https://aws.amazon.com/blogs/storage/how-to-optimize-querying-your-data-in-amazon-s3/) 

在 Amazon EMR 发行版 5.17.0 及更高版本中，您可以将 [S3 Select](https://aws.amazon.com/blogs/aws/s3-glacier-select/) 与 Amazon EMR 上的 Spark 结合使用。*S3 Select* 可让应用程序仅从对象检索数据子集。对于 Amazon EMR，筛选要处理的大型数据集的计算工作是从集群“向下推送”到 Amazon S3，这可以在某些应用程序中提高性能和减少 Amazon EMR 与 Amazon S3 之间传输的数据量。

S3 Select 支持使用 `s3selectCSV` 和 `s3selectJSON` 值来指定数据格式的 CSV 和 JSON 文件。有关更多信息以及示例，请参阅 [在代码中指定 S3 Select](#emr-spark-s3select-specify)。

## S3 Select 是否适合我的应用程序？
<a name="emr-spark-s3select-apps"></a>

建议您分别在使用和不使用 S3 Select 的情况下测试您的应用程序，以查看 S3 Select 是否适用于您的应用程序。

使用以下准则来确定您的应用程序是否为使用 S3 Select 的候选项：
+ 您的查询将筛选掉原始数据集的一半以上的数据。
+ 您在 Amazon S3 和 Amazon EMR 集群之间的网络连接具有良好的传输速度和可用带宽。Amazon S3 不压缩 HTTP 响应，因此响应大小可能会根据压缩的输入文件而增大。

## 注意事项和限制
<a name="emr-spark-s3select-considerations"></a>
+ 使用客户提供的加密密钥进行的 Amazon S3 服务器端加密（SSE-C）与客户端加密都不受支持。
+ 不支持 `AllowQuotedRecordDelimiters` 属性。如果指定该属性，则查询将失败。
+ 仅支持采用 UTF-8 格式的 CSV 和 JSON 文件。不支持 CSVs多行。
+ 仅支持未压缩文件或 gzip 文件。
+ 不支持 Spark CSV 和 JSON 选项（如 `nanValue`、`positiveInf`、`negativeInf`）以及与损坏记录相关的选项（例如，failfast 和 dropmalformed 模式）。
+ 不支持在十进制数中使用逗号 (,)。例如，不支持 `10,000`，支持 `10000`。
+ 不支持最后一行中的注释字符。
+ 文件末尾的空行不会被处理。
+ 以下筛选条件不会向下推送到 Amazon S3：
  + 聚合函数（如 `COUNT()` 和 `SUM()`）。
  + 对属性进行 `CAST()` 的筛选条件。例如 `CAST(stringColumn as INT) = 1`。
  + 具有作为对象或很复杂的属性的筛选条件。例如 `intArray[1] = 1, objectColumn.objectNumber = 1`。
  + 值不是文本值的筛选条件。例如，`intColumn1 = intColumn2`
  + 仅支持 [S3 Select 支持的数据类型](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-glacier-select-sql-reference-data-types.html)，但存在记录的限制。

## 在代码中指定 S3 Select
<a name="emr-spark-s3select-specify"></a>

以下示例演示如何使用 Scala、SQL、R 和 PySpark为 CSV 指定 S3 Select。您可以通过同样的方法使用适用于 JSON 的 S3 Select。有关选项、默认值和限制的列表，请参阅[选项](#emr-spark-s3select-specify-options)。

------
#### [ PySpark ]

```
spark
  .read
  .format("s3selectCSV") // "s3selectJson" for Json
  .schema(...) // optional, but recommended
  .options(...) // optional
  .load("s3://path/to/my/datafiles")
```

------
#### [ R ]

```
read.df("s3://path/to/my/datafiles", "s3selectCSV", schema, header = "true", delimiter = "\t")
```

------
#### [ Scala ]

```
spark
  .read
  .format("s3selectCSV") // "s3selectJson" for Json
  .schema(...) // optional, but recommended
  .options(...) // optional. Examples:  
  // .options(Map("quote" -> "\'", "header" -> "true")) or
  // .option("quote", "\'").option("header", "true")
  .load("s3://path/to/my/datafiles")
```

------
#### [ SQL ]

```
CREATE TEMPORARY VIEW MyView (number INT, name STRING) USING s3selectCSV OPTIONS (path "s3://path/to/my/datafiles", header "true", delimiter "\t")
```

------

### 选项
<a name="emr-spark-s3select-specify-options"></a>

使用 `s3selectCSV` 和 `s3selectJSON` 时，有以下选项可用。如果未指定，将使用默认值。

#### 使用 S3selectCSV 时的选项
<a name="emr-spark-s3select-specify-options-csv"></a>


| Option | 默认 | 用法 | 
| --- | --- | --- | 
|  `compression`  |  `"none"`  |  指示是否使用了压缩。`"gzip"` 是除 `"none"` 之外唯一受支持的设置。  | 
|  `delimiter`  |  ","  |  指定字段分隔符。  | 
|  `quote`  |  `'\"'`  |  指定引号字符。不支持指定空字符串，这样做会导致 XML 格式不正确错误。  | 
|  `escape`  |  `'\\'`  |  指定转义字符。  | 
|  `header`  |  `"false"`  |  `"false"` 指定不存在标头。`"true"` 指定第一行中存在标头。仅支持第一行中的标头，不支持标头前面的空行。  | 
|  comment  |  `"#"`  |  指定注释字符。无法禁用注释标记。换句话说，不支持值 `\u0000`。  | 
|  `nullValue`  |  ""  |    | 

#### 使用 S3selectJSON 时的选项
<a name="emr-spark-s3select-specify-options-json"></a>


| Option | 默认 | 用法 | 
| --- | --- | --- | 
|  `compression`  |  `"none"`  |  指示是否使用了压缩。`"gzip"` 是除 `"none"` 之外唯一受支持的设置。  | 
|  `multiline`  |  “false”  |  `"false"` 指定 JSON 采用 S3 Select `LINES` 格式，这意味着输入数据中的每个行都包含单个 JSON 对象。`"true"` 指定 JSON 采用 S3 Select `DOCUMENT` 格式，这意味着 JSON 对象可跨输入数据中的多个行。  | 