

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

# 建立分區索引
<a name="partition-indexes"></a>

隨著時間的推移，數十萬個分割區被新增到資料表中。[GetPartitions API](https://docs.aws.amazon.com/glue/latest/webapi/API_GetPartitions.html) 用於擷取資料表中的分割區。API 會傳回符合請求中所提供表達式的分區。

讓我們以 *sales\$1data* 資料表為例，其由 *Country*、*Category*、*Year*、*Month* 和 *creationDate* 索引鍵分區。如果想要取得 2020 年度 *2020 年 8 月 15 日之後* *Books* 類別的所有銷售項目，則必須使用表達式 "Category = 'Books' and creationDate > '2020-08-15'" 對 Data Catalog 發出 `GetPartitions` 請求。

如果資料表上沒有分割區索引，AWS Glue 會載入資料表的所有分割區，然後使用使用者在 `GetPartitions` 請求中提供的查詢表達式來篩選載入的分割區。查詢需要更多的時間來執行，因為沒有索引的資料表上的分割區數目會增加。使用索引，`GetPartitions` 查詢可嘗試擷取分割區的子集，而不是載入資料表中的所有分割區。

**Topics**
+ [關於分割區索引](#partition-index-1)
+ [建立具有分割區索引的資料表](#partition-index-creating-table)
+ [將分割區索引新增至現有資料表](#partition-index-existing-table)
+ [描述資料表上的分割區索引](#partition-index-describing)
+ [使用分割區索引的限制](#partition-index-limitations)
+ [使用索引進行最佳化的 GetPartitions 呼叫](#partition-index-getpartitions)
+ [與引擎整合](#partition-index-integration-engines)

## 關於分割區索引
<a name="partition-index-1"></a>

在您建立分割區索引時，指定已存在於指定資料表上的分割區索引鍵清單。分割區索引是在資料表中定義的分割區索引鍵的子清單。分割區索引可以在資料表上定義的分割區索引鍵的任何排列上建立。對於上述 *sales\$1data* 資料表，可能的索引包括 (country, category, creationDate)、(country, category, year)、(country, category)、(country)、(category, country, year, month) 等。

 Data Catalog 會依建立索引時提供的順序連接分割區值。當分割區新增至資料表時，索引會一致地建立。可以針對字串 (string、char 和 varchar)、數字 (int、bigint、long、tinyint 和 smallint) 和日期 (yyyy-MM-dd) 資料欄類型建立索引。

**支援的資料類型**
+ 日期 – ISO 格式的日期，例如 `YYYY-MM-DD`。例如，日期 `2020-08-15`。該格式使用連字號 (‐) 來分隔年、月和日。索引的允許日期範圍從 `0000-01-01` 到 `9999-12-31`。
+ 字串 – 用單引號或雙引號括住的字串文字。
+ 字元 – 固定長度的字元資料，介於 1 到 255 的指定長度，例如 char(10)。
+ 可變字元 – 可變長度的字元資料，介於 1 到 65535 的指定長度，例如 varchar(10)。
+ 數值 – int、biint、long、tinyint 和 smallint

數值、字串、日期資料類型的索引支援 =、>、> =、<、<= 以及 between 運算子。索引解決方案目前只支援 `AND` 邏輯運算子。使用索引進行篩選的表達式會忽略具有運算子「LIKE」、「IN」、「OR」和「NOT」的子表達式。篩選忽略的子表達式會在套用索引篩選之後擷取的分割區上完成。

對於新增到資料表中的每個分割區，會有一個相應的索引項目建立。對於具有 'n' 個分割區的資料表，1 個分割區索引會產生 'n' 個分割區索引項目。同一個資料表上的 'm' 個分割區索引會產生 'm\$1n' 個分割區索引項目。每個分割區索引項目將根據目前的 AWS Glue Data Catalog 儲存體的定價政策。如需儲存物件定價的詳細資訊，請參閱 [AWS Glue 定價](https://aws.amazon.com/glue/pricing/)。

## 建立具有分割區索引的資料表
<a name="partition-index-creating-table"></a>

您可以在建立資料表期間建立分割區索引。`CreateTable` 要求會取得 [`PartitionIndex` 物件](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api-catalog-tables.html#aws-glue-api-catalog-tables-PartitionIndex)的清單作為輸入。指定資料表上最多可以建立 3 個分割區索引。每個分割區索引都需要一個名稱和為資料表定義的 `partitionKeys` 清單。在資料表上建立的索引可以使用 [`GetPartitionIndexes` API](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api-catalog-tables.html#aws-glue-api-catalog-tables-GetPartitionIndexes) 擷取

## 將分割區索引新增至現有資料表
<a name="partition-index-existing-table"></a>

若要將分割區索引新增至現有資料表，請使用 `CreatePartitionIndex` 操作。每個 `CreatePartitionIndex` 操作只能建立一個 `PartitionIndex`。新增索引不會影響資料表的可用性，因為資料表會在建立索引時繼續可用。

新增分割區的索引狀態設定為 CREATING，並啟動索引資料的建立。如果建立索引的處理程序成功，indexStatus 會更新為 ACTIVE，並且對於不成功的處理程序，索引狀態會更新為 FAILED。索引建立可能會因多種原因而失敗，您可以使用 `GetPartitionIndexes` 作業擷取失敗詳細資訊。可能失敗如下：
+ ENCRYPTED\$1PARTITION\$1ERROR — 不支援在具有加密分割區的資料表上建立索引。
+ INVALID\$1PARTITION\$1TYPE\$1DATA\$1ERROR — 當 `partitionKey` 值不是對應 `partitionKey` 資料類型的有效值時觀察到。例如：具有 'int' 資料類型的 `partitionKey` 有一個 'foo' 值。
+ MISSING\$1PARTITION\$1VALUE\$1ERROR — 當 `indexedKey` 的 `partitionValue` 不存在時觀察到。當資料表沒有一致地進行分割時，可能會發生這種情況。
+ UNSUPPORTED\$1PARTITION\$1CHARACTER\$1ERROR — 當索引分割區索引鍵的值包含字元 \$1u0000、\$1u0001 或 \$1u0002 時觀察到。
+ INTERAL\$1ERROR — 建立索引時發生內部錯誤。

## 描述資料表上的分割區索引
<a name="partition-index-describing"></a>

若要擷取資料表上建立的分割區索引，請使用 `GetPartitionIndexes` 操作。回應會傳回資料表上的所有索引，以及每個索引的目前狀態 (`IndexStatus`)。

分割區索引的 `IndexStatus` 會是下列其中一項：
+ `CREATING` – 正在建立索引，尚無法使用。
+ `ACTIVE`— 索引已準備就緒可供使用。請求可以使用索引來執行最佳化的查詢。
+ `DELETING` – 正在刪除索引，無法再使用。處於活動狀態的索引可以使用 `DeletePartitionIndex` 請求，該請求將狀態從 ACTIVE 移動到 DELETING。
+ `FAILED` — 在現有資料表上建立索引失敗。每個資料表儲存最後 10 個失敗的索引。

在現有資料表上建立的索引的可能狀態轉換是：
+ CREATING → ACTIVE → DELETING
+ CREATING → FAILED

## 使用分割區索引的限制
<a name="partition-index-limitations"></a>

建立分割區索引之後，請注意下列資料表和分割區功能變更：

**建立新分區 (新增索引之後)**  
在資料表上建立分割區索引之後，新增至資料表的所有新分割區都會驗證索引鍵的資料類型檢查。索引索引鍵的分割區值將針對資料類型格式進行驗證。如果資料類型檢查失敗，建立分割區作業將會失敗。對於 *sales\$1data*，如果針對 (category, year) 索引鍵建立索引，其中 category 為 `string` 類型且 year 為 `int` 類型，則建立具有 YEAR 值為「foo」的新分割區將失敗。

啟用索引之後，新增具有索引索引鍵值的分割區，其字元為 U\$10000、U\$100001 和 U\$10002 將會開始失敗。

**資料表更新**  
在資料表上建立分割區索引之後，您就無法修改現有分割區索引鍵的分割區索引鍵名稱，也無法變更與索引註冊之索引鍵的類型或順序。

## 使用索引進行最佳化的 GetPartitions 呼叫
<a name="partition-index-getpartitions"></a>

當您在具有索引的資料表上呼叫 `GetPartitions`，您可以包含表達式，如果適用， Data Catalog 將使用索引 (如果可能)。索引的第一個索引鍵應該在用於篩選索引的表達式中傳遞。篩選中的索引最佳化會盡最大努力應用。 Data Catalog 會嘗試盡可能使用索引最佳化，但如果遺失索引或不受支援的運算子，它會回退到載入所有分割區的現有實作。

於上述 *sales\$1data* 資料表，讓我們新增索引 [Country, Category, Year]。如果表達式中未傳遞 "Country"，註冊的索引將無法使用索引篩選分割區。您最多可以新增 3 個索引，以支援各種查詢模式。

讓我們舉一些範例表達式，看看索引如何在它們上運作：


| 表達式 | 索引的使用方式 | 
| --- | --- | 
|  Country = 'US'  |  索引將用於篩選分割區。  | 
|  Country = 'US' and Category = 'Shoes'  |  索引將用於篩選分割區。  | 
|  Category = 'Shoes'  |  表達式中沒有提供 "country"，所以不會使用索引。所有分割區將被載入以傳回回應。  | 
|  Country = 'US' and Category = 'Shoes' and Year > '2018'  |  索引將用於篩選分割區。  | 
|  Country = 'US' and Category = 'Shoes' and Year > '2018' and month = 2  |  索引將用於擷取 country = "US" 和 category = "shoes" 和 year > 2018 的所有分割區。然後，將執行月份表達式上的篩選。  | 
|  Country = 'US' AND Category = 'Shoes' OR Year > '2018'  |  由於 `OR` 運算子存在於表達式中，因此不會使用索引。  | 
|  Country = 'US' AND Category = 'Shoes' AND (Year = 2017 OR Year = '2018')  |  索引將用於擷取 country = "US" 和 category = "shoes" 的所有分割區然後執行對年份表達式的篩選。  | 
|  Country in ('US', 'UK') AND Category = 'Shoes'  |  由於目前不支援 `IN` 運算子，因此不會使用索引進行篩選。  | 
|  Country = 'US' AND Category in ('Shoes', 'Books')  |  索引將用於擷取具有 country = "US" 的所有分割區，然後執行對「類別」表達式的篩選。  | 
|  Country = 'US' AND Category in ('Shoes', 'Books') AND (creationDate > '2023-9-01'  |  索引將用於擷取 country = "US" 且 creationDate > '2023-9-01' 的所有分區，然後執行對「類別」表達式的篩選。  | 

## 與引擎整合
<a name="partition-index-integration-engines"></a>

AWS Glue 中的索引處於 ACTIVE 狀態後，Redshift Spectrum、Amazon EMR 和 AWS Glue ETL Spark DataFrames 就可以利用索引來擷取分區。[Athena](https://docs.aws.amazon.com/athena/latest/ug/glue-best-practices.html#glue-best-practices-partition-index) 和 [AWS Glue ETL 動態框架](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-partitions.html#aws-glue-programming-etl-partitions-cat-predicates)會要求您遵循額外的步驟以利用索引進行查詢改進。

### 啟用分區篩選
<a name="enable-partition-filtering-athena"></a>

若要在 Athena 中啟用分區篩選，需要更新資料表屬性，如下所示：

1. 在 AWS Glue 主控台**的資料目錄**下，選擇**資料表**。

1. 選擇 表格。

1. 在**動作**下，選擇**編輯資料表**。

1. 在**資料表屬性**下，新增下列項目：
   + 索引鍵 –`partition_filtering.enabled`
   + 值 – `true`

1. 選擇**套用**。

或者，也可以在 Athena 中執行 [ALTER TABLE SET PROPERTIES](https://docs.aws.amazon.com/athena/latest/ug/alter-table-set-tblproperties.html) 查詢來設定此參數。

```
ALTER TABLE partition_index.table_with_index
SET TBLPROPERTIES ('partition_filtering.enabled' = 'true')
```