

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 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：
+ 您的查詢會篩選掉原始資料集一半以上的資料。
+ Amazon S3 與 Amazon EMR 叢集之間的網路連線具有良好的傳輸速度和可用頻寬。Amazon S3 不會壓縮 HTTP 回應，因此所壓縮輸入檔案的回應大小可能會增加。

## 考量和限制
<a name="emr-spark-s3select-considerations"></a>
+ 不支援使用客戶所提供加密金鑰 (SSE-C) 的 Amazon S3 伺服器端加密，也不支援用戶端加密。
+ 不支援 `AllowQuotedRecordDelimiters` 屬性。如果指定此屬性，查詢會失敗。
+ 僅支援採用 UTF-8 格式的 CSV 和 JSON 檔案。不支援多行 CSV。
+ 僅支援未壓縮的檔案或 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>


| 選項 | 預設 | Usage | 
| --- | --- | --- | 
|  `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>


| 選項 | 預設 | Usage | 
| --- | --- | --- | 
|  `compression`  |  `"none"`  |  指出是否使用了壓縮。`"gzip"` 是除了 `"none"` 之外唯一支援的設定。  | 
|  `multiline`  |  "false"  |  `"false"` 指定 JSON 為 S3 Select `LINES` 格式，這表示輸入資料中的每一行都包含了單一 JSON 物件。`"true"` 指定 JSON 為 S3 Select `DOCUMENT` 格式，這表示一個 JSON 物件可在輸入資料中跨越多行。  | 