

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

# 最佳化資料
<a name="performance-tuning-data-optimization-techniques"></a>

效能不僅取決於查詢，而且還取決於資料集的組織方式，以及資料集使用的檔案格式和壓縮。

## 分割您的資料
<a name="performance-tuning-partition-your-data"></a>

分割會將您的資料表分為多個部分，並根據日期、國家或地區等屬性將相關資料保留在一起。分割區索引鍵可可做為虛擬資料欄。您可以在建立資料表時定義分割區索引鍵，並使用它們來篩選查詢。當您篩選分割區索引鍵資料欄時，只會讀取相符分割區中的資料。例如，如果您的資料集依日期進行分割，而您的查詢具有僅符合上週的篩選條件，則只會讀取上週的資料。如需有關分割區的詳細資訊，請參閱 [分割您的資料](partitions.md)。

## 選擇將支援您查詢的分割區索引鍵
<a name="performance-tuning-pick-partition-keys-that-will-support-your-queries"></a>

由於分割會對查詢效能產生重大影響，因此在設計資料集和資料表時，請務必仔細考慮分割的方式。分割區索引鍵太多可能會導致資料集分段為過多的檔案且各個檔案過小。相反地，分割區索引鍵太少或完全沒有分割，會導致查詢掃描的資料超過必要的資料。

### 避免最佳化罕見查詢
<a name="performance-tuning-avoid-optimizing-for-rare-queries"></a>

一個好的策略是針對最常見的查詢進行最佳化，並避免針對罕見查詢進行最佳化。例如，如果您的查詢瀏覽時間跨度 (天數)，即使某些查詢會篩選至該級別，也不要按小時進行分割。如果您的資料具有精確的時間戳記資料欄，則依小時篩選的罕見查詢可以使用時間戳記資料欄。即使極少數情況掃描的資料超過必要的資料，為了極少數情況而降低整體效能通常不是一種很好的權衡。

若要減少查詢必須掃描的資料量，進而改善效能，請使用單欄式檔案格式，並保持記錄排序。請依時間戳記排序記錄，而不是依小時分割。對於在較短時間視窗上進行查詢，按時間戳記排序的效率幾乎與依小時分割一樣有效。此外，依時間戳記排序通常不會損害時間視窗上的查詢效能 (以天數計算)。如需詳細資訊，請參閱[使用單欄式檔案格式](#performance-tuning-use-columnar-file-formats)。

請注意，如果所有分割區索引鍵都有述詞，則對具有數萬個分割區的資料表進行查詢的效果會更好。這是為最常見的查詢設計分割結構的另一個原因。如需詳細資訊，請參閱[依等式查詢分割區](#performance-tuning-query-partitions-by-equality)。

## 使用分割區投影
<a name="performance-tuning-use-partition-projection"></a>

分割區投影是一種 Athena 功能，可儲存不在 中的分割區資訊 AWS Glue Data Catalog，但做為 資料表屬性中的規則 AWS Glue。當 Athena 在設定了分割區投影的資料表上計劃查詢時，其會讀取資料表的分割區投影規則。Athena 會根據查詢和規則，計算要在記憶體中讀取的分割區，而不是在 AWS Glue Data Catalog中查找分割區。

除了簡化分割區管理之外，分割區投影還可以改善具有大量分割區的資料集的效能。當查詢包含範圍而不是分割區索引鍵的特定值時，在目錄中查找相符分割區所花費的時間越長，所需的分割區就越多。使用分割區投影，可以在記憶體中計算篩選條件而無需進入目錄，並且速度可以更快。

在某些情況下，分割區投影可能會導致效能變差。一個範例就是當資料表為「稀疏」時。稀疏資料表沒有分割區投影組態所描述的分割區索引鍵值的每個排列資料。使用稀疏資料表時，從查詢和分割區投影組態計算的一組分區都會列在 Amazon S3 上，即使它們沒有資料也一樣。

當您使用分割區投影時，請務必在所有分割區索引鍵上包含述詞。縮小可能值的範圍，以避免不必要的 Amazon S3 清單。假設一個分割區索引鍵的範圍包含一百萬個值，以及查詢在該分割區索引鍵上沒有任何篩選條件。若要執行查詢，Athena 必須執行至少一百萬個 Amazon S3 清單操作。查詢特定值時，無論您是使用分割區投影還是將分割區資訊儲存在目錄中，查詢速度都是最快的。如需詳細資訊，請參閱[依等式查詢分割區](#performance-tuning-query-partitions-by-equality)。

當您設定分割區投影的資料表時，請確定您指定的範圍是合理的。如果查詢不包含分割區索引鍵的述詞，則會使用該索引鍵範圍內的所有值。如果您的資料集是在特定日期建立的，請使用該日期做為任何日期範圍的起點。使用 `NOW` 作為日期範圍的結束。避免使用具有大量值的數值範圍，並考慮改用[注入](partition-projection-dynamic-id-partitioning.md#partition-projection-injection)類型。

如需有關分割區投影的詳細資訊，請參閱[透過 Amazon Athena 使用分割區投影](partition-projection.md)。

## 使用分割區索引
<a name="performance-tuning-use-partition-indexes"></a>

分割區索引是 中的一項功能 AWS Glue Data Catalog ，可改善具有大量分割區之資料表的分割區查詢效能。

目錄中的分割區清單就像是關聯式資料庫中的資料表。此資料表包含分割區索引鍵的資料欄，以及分割區位置的其他資料欄。當您查詢分割區資料表時，會掃描此資料表來查詢分割區位置。

就像關聯式資料庫一樣，您可以透過新增索引來提高查詢的效能。您可以新增多個索引，以支援不同的查詢模式。 AWS Glue Data Catalog 分割區索引支援等式運算子和比較運算子`>`，例如 `>=`、 和 與運算`AND`子`<`結合。如需詳細資訊，請參閱《 *AWS Glue 開發人員指南*》中的[在 中使用分割區索引 AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/partition-indexes.html)，以及《 *AWS 大數據部落格*》中的[使用 AWS Glue Data Catalog 分割區索引改善 Amazon Athena 查詢效能](https://aws.amazon.com/blogs/big-data/improve-amazon-athena-query-performance-using-aws-glue-data-catalog-partition-indexes/)。

## 始終使用 STRING 做為分割區索引鍵類型
<a name="performance-tuning-always-use-string-as-the-type-for-partition-keys"></a>

當您查詢分割區索引鍵時，請記住 Athena 要求分割區索引鍵為類型 `STRING`，才能將分割區篩選下推至 AWS Glue。如果分割區數目不小，使用其他類型可能會導致效能變差。如果您的分割區索引鍵值為 date-like 或 number-like，請將它們轉換為查詢中的適當類型。

## 移除舊的和空的分割區
<a name="performance-tuning-remove-old-and-empty-partitions"></a>

如果您從 Amazon S3 上的分割區移除資料 (例如，使用 Amazon S3 [生命週期](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html))，您也應該從 AWS Glue Data Catalog中移除分割區項目。在查詢規劃期間，與查詢相符的任何分割區都會列在 Amazon S3 上。如果您有許多空的分割區，列出這些分割區的負荷可能會產生不利影響。

此外，如果您有數千個分割區，請考慮移除不再相關的舊資料的分割區中繼資料。例如，如果查詢從未查看超過一年的資料，您可以定期移除舊分割區的分割區中繼資料。如果分割區數目增加到數萬個，移除未使用的分割區可以加速查詢，其中這些查詢不包含所有分割區索引鍵的述詞。如需有關在查詢中包含所有分割區索引鍵的述詞的資訊，請參閱 [依等式查詢分割區](#performance-tuning-query-partitions-by-equality)。

## 依等式查詢分割區
<a name="performance-tuning-query-partitions-by-equality"></a>

在所有分割區索引鍵上包含等式述詞的查詢執行速度更快，因為可以直接載入分割區中繼資料。避免查詢中一個或多個分割區索引鍵沒有述詞，或述詞選擇了範圍值。對於此類查詢，必須篩選所有分割區的清理，以找到相符的值。對於大多數資料表而言，負荷會降至最低，但對於具有數萬個或更多分割區的資料表而言，負荷可能會變得很大。

如果無法重寫查詢以透過等式篩選分割區，則可以嘗試分割區投影。如需詳細資訊，請參閱[使用分割區投影](#performance-tuning-use-partition-projection)。

## 避免使用 MSCK REPAIR TABLE 進行分割區維護
<a name="performance-tuning-avoid-using-msck-repair-table-for-partition-maintenance"></a>

由於 `MSCK REPAIR TABLE` 可能需要很長的時間才能執行，並且僅會新增分割區，而不會移除舊的分割區，因此不是管理分割區的有效方法 (請參閱 [考量和限制](msck-repair-table.md#msck-repair-table-considerations))。

使用 [AWS Glue Data Catalog API](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api-catalog.html)、[ALTER TABLE ADD PARTITION](alter-table-add-partition.md) 或 [AWS Glue 爬蟲程式](https://docs.aws.amazon.com/glue/latest/dg/crawler-running.html)可以更好地手動管理分割區。或者，您也可以使用分割區投影，這樣就不需要完全管理分割區。如需詳細資訊，請參閱[透過 Amazon Athena 使用分割區投影](partition-projection.md)。

## 驗證您的查詢是否與分割結構相容
<a name="performance-tuning-validate-that-your-queries-are-compatible-with-the-partitioning-scheme"></a>

您可以使用 [`EXPLAIN`](athena-explain-statement.md) 陳述式預先檢查查詢將掃描的分割區。使用 `EXPLAIN` 關鍵字作為查詢字首，然後在 `EXPLAIN` 輸出底部附近查找每個資料表的來源片段 (例如，`Fragment 2 [SOURCE]`)。查找右側被定義為分割區索引鍵的指派。下方的列包含一份清單，列出執行查詢時將要掃描的該分割區索引鍵的所有值。

例如，假設您對具有 `dt` 分割區索引鍵的資料表進行查詢，並使用 `EXPLAIN` 作為查詢字首。如果查詢中的值是日期，並且篩選條件選取了三天的範圍，則 `EXPLAIN` 輸出可能如下所示：

```
dt := dt:string:PARTITION_KEY
    :: [[2023-06-11], [2023-06-12], [2023-06-13]]
```

`EXPLAIN` 輸出顯示，規劃程式找到了此分割區索引鍵的三個值，且其與查詢相符。它還顯示了這些值是什麼。如需有關使用 `EXPLAIN` 的詳細資訊，請參閱 [在 Athena 使用 EXPLAIN 和 EXPLAIN ANALYZE](athena-explain-statement.md) 和 [了解 Athena EXPLAIN 陳述式結果](athena-explain-statement-understanding.md)。

## 使用單欄式檔案格式
<a name="performance-tuning-use-columnar-file-formats"></a>

專為分散式分析工作負載而設計的單欄式檔案格式，例如 Parquet 和 ORC。它們依資料欄而非資料列整理資料。以單欄式格式整理資料具有下列優點：
+ 僅會載入查詢所需的資料欄
+ 減少需要載入的整體資料量
+ 資料欄值會一起存放，因此可以有效地壓縮資料 
+ 檔案可以包含允許引擎略過載入不需要的資料的中繼資料

做為如何使用檔案中繼資料的範例，檔案中繼資料可以包含有關資料頁面中最小值和最大值的資訊。如果查詢的值不在中繼資料中註明的範圍內，則可以略過該頁面。

使用此中繼資料提高效能的一種方法是，確定對檔案中的資料進行排序。例如，假設您有查詢會尋找 `created_at` 項目在短時間範圍內的記錄。如果您的資料依 `created_at` 資料欄排序，Athena 可以使用檔案中繼資料中的最小值和最大值來略過資料檔案中不需要的部分。

使用單欄式檔案格式時，請確定檔案不會太小。如 [避免檔案太多](#performance-tuning-avoid-having-too-many-files) 中所述，含有許多小型檔案的資料集會造成效能問題。對於單欄式檔案格式而言，尤其如此。對於小型檔案，單欄式檔案格式的負荷超過優勢。

請注意，Parquet 和 ORC 在內部依資料列群組 (Parquet) 和條紋 (ORC) 進行整理。資料列群組的預設大小為 128 MB，而條紋的預設大小則為 64 MB。如果您有許多資料欄，您可以增加資料列群組和條紋大小，以提升效能。不建議將資料列群組或條紋大小減少至小於其預設值。

若要將其他資料格式轉換為 Parquet 或 ORC，您可以使用 AWS Glue ETL 或 Athena。如需詳細資訊，請參閱[轉換為單欄式格式](columnar-storage.md#convert-to-columnar)。

## 壓縮資料
<a name="performance-tuning-compress-data"></a>

Athena 支援各種壓縮格式。查詢壓縮資料的速度更快，也更便宜，因為您需要為解壓縮前掃描的位元組數量進行支付。

[gzip](https://www.gnu.org/software/gzip/) 格式提供了良好的壓縮比，並且在其他工具和服務中具有廣泛的支援。[zstd](https://facebook.github.io/zstd/) (Zstandard) 格式是一種較新的壓縮格式，可使效能和壓縮比之間達到良好的平衡。

壓縮文字檔案 (例如 JSON 和 CSV 資料) 時，請嘗試在檔案數量和檔案大小之間取得平衡。大多數壓縮格式都要求讀者從頭開始讀取檔案。這表示一般而言，壓縮的文字檔案無法平行處理。大型未壓縮的檔案通常會在工作者之間分割，以在查詢處理期間達到更高的平行處理能力，但大多數壓縮格式無法執行這項操作。

如 [避免檔案太多](#performance-tuning-avoid-having-too-many-files) 中所述，檔案最好不要太多也不宜過少。由於檔案數目是可處理查詢的工作者數量限制，因此對於壓縮檔案而言，此規則尤其如此。

如需有關在 Athena 中使用壓縮的詳細資訊，請參閱 [在 Athena 中使用壓縮](compression-formats.md)。

## 使用歸納來查詢具有高基數的索引鍵
<a name="performance-tuning-use-bucketing-for-lookups-on-keys-with-high-cardinality"></a>

歸納是一種技術，可根據其中一個資料欄的值，將記錄分佈至個別檔案中。這能確保具有相同值的所有記錄都位於同一個檔案中。當您擁有高基數的索引鍵，而且許多查詢都會查詢索引鍵的特定值時，歸納功能非常有用。

例如，假設您查詢特定使用者的一組記錄。如果資料是依使用者 ID 歸納，Athena 會事先知道哪些檔案包含特定 ID 的記錄，哪些檔案不包含。這可讓 Athena 僅讀取包含 ID 的檔案，進而大幅減少讀取的資料量。這同意也可減少在資料中搜尋特定 ID 所需的運算時間。

### 當查詢頻繁搜尋資料欄中的多個值時，請避免使用歸納
<a name="performance-tuning-disadvantages-of-bucketing"></a>

當查詢經常在資料歸納的資料欄中搜尋多個值時，歸納的價值就不太重要。查詢的值越多，必須讀取所有或大部分檔案的可能性就越高。例如，如果您有三個儲存貯體，而查詢會尋找三個不同的值，則可能必須讀取所有檔案。當查詢在查找單一值時，歸納效果最佳。

如需詳細資訊，請參閱[使用分割和歸納](ctas-partitioning-and-bucketing.md)。

## 避免檔案太多
<a name="performance-tuning-avoid-having-too-many-files"></a>

由許多小型檔案組成的資料集會導致整體查詢效能不佳。Athena 計劃查詢時，會列出所有分割區位置，而這需要花費一些時間。處理和請求每個檔案也會產生運算負載。因此，從 Amazon S3 載入單一較大的檔案比從許多較小的檔案載入相同記錄更快。

在極端情況下，您可能會遇到 Amazon S3 服務限制。針對單一索引分割區，Amazon S3 每秒最多可支援 5,500 個請求。最初，儲存貯體會被視為單一索引分割區，但隨著請求載入的增加，它可以分割成多個索引分割區。

Amazon S3 會根據索引鍵字首查詢請求模式和分割。如果您的資料集包含數千個檔案，則來自 Athena 的請求可能會超出請求的配額。即使檔案較少，如果對同一個資料集進行多個並行查詢，則可能會超過配額。存取相同檔案的其他應用程式可能會增加請求總數。

當超出請求率 `limit` 時，Amazon S3 會傳回下列錯誤。此錯誤已包含在 Athena 查詢的狀態資訊中。

 SlowDown：請降低請求率 

若要進行疑難排解，請先判斷錯誤是由單一查詢還是由可讀取相同檔案的多個查詢造成的。如果是後者，請協調查詢的執行，以便它們不會同時執行。為此，請在應用程式中新增佇列機制，甚至是重試。

如果執行單一查詢觸發錯誤，請嘗試合併資料檔案或修改查詢，以讀取較少的檔案。合併小型檔案的最佳時間是在將其寫入之前。為此，請考慮下列技巧：
+ 變更寫入檔案的程序，以寫入較大的檔案。例如，您可以在寫入記錄之前緩衝一段較長的時間。
+ 將檔案放在 Amazon S3 上的某個位置，然後使用 Glue ETL 等工具將其合併為較大的檔案。然後，將較大的檔案移至資料表所指向的位置。如需詳細資訊，請參閱《 *AWS Glue 開發人員指南*》中的[讀取較大群組中的輸入檔案](https://docs.aws.amazon.com/glue/latest/dg/grouping-input-files.html)，以及[如何在 re：Post 知識中心中設定 AWS Glue ETL 任務以輸出較大的檔案？](https://repost.aws/knowledge-center/glue-job-output-large-files)。 *AWS *
+ 減少分割區索引鍵的數量。當您的分割區索引鍵太多時，每個分割區可能只有少數記錄，因此會產生過多的小型檔案。如需有關決定要建立哪些分割區的資訊，請參閱 [選擇將支援您查詢的分割區索引鍵](#performance-tuning-pick-partition-keys-that-will-support-your-queries)。

## 避免分割區以外的其他儲存體階層
<a name="performance-tuning-avoid-additional-storage-hierarchies-beyond-the-partition"></a>

若要避免查詢規劃負荷，請將檔案儲存在每個分割區位置的單層式結構中。請勿使用任何其他目錄階層。

Athena 計劃查詢時，會列出與查詢相符的所有分割區中的所有檔案。雖然 Amazon S3 本身沒有目錄，但慣例是將 `/` 斜線解譯為目錄分隔符號。當 Athena 列出分割區位置時，其會遞歸列出找到的任何目錄。當分割區內的檔案整理成階層時，會出現多輪清單。

當所有檔案都直接位於分割區位置時，大多數情況下只需執行一個清單操作。但是，如果一個分割區中有 1000 個以上的檔案，則需要多個連續清單操作，因為 Amazon S3 每個清單操作只會傳回 1000 個物件。分區中有 1000 多個檔案也可能會導致其他更嚴重的效能問題。如需詳細資訊，請參閱[避免檔案太多](#performance-tuning-avoid-having-too-many-files)。

## 僅在必要時使用 SymlinkTextInputFormat
<a name="performance-tuning-use-symlinktextinputformat-only-when-necessary"></a>

使用 [https://athena.guide/articles/stitching-tables-with-symlinktextinputformat](https://athena.guide/articles/stitching-tables-with-symlinktextinputformat) 技術可以是一種解決相關情況的方法，當資料表的檔案沒有整齊地整理到分割區中時。例如，當所有檔案都使用相同的字首，或是具有不同結構描述的檔案位於相同位置時，符號連結可能很有用。

但是，使用符號連結會為查詢執行增加間接層級。這些間接層級會影響整體效能。必須讀取符號連結檔案，並且必須列出它們定義的位置。如此會新增至 Amazon S3 的多次往返，而這並非常見 Hive 資料表所需的。總之，只有當沒有更好的選項 (例如整理檔案) 可用時，您才應使用 `SymlinkTextInputFormat`。