Athena 中的效能調校 - Amazon Athena

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

Athena 中的效能調校

本主題就改善 Athena 查詢效能以及如何解決與限制和資源使用量相關的錯誤,提供了一般資訊和具體建議。

Service Quotas

Athena 會針對查詢執行時間、帳戶中的並行查詢數目以及 API 請求率等指標強制執行配額。如需有關這些配額的詳細資訊,請參閱 Service Quotas。超過這些配額會導致查詢失敗 – 無論是在提交查詢時還是在查詢執行期。

此頁面上的許多效能最佳化秘訣可協助縮短查詢的執行時間。最佳化可釋出容量,以便您可以在並行配額內執行更多查詢,並避免查詢因執行時間過長而被取消。

並行查詢和 API 請求數量的配額是每個 AWS 帳戶 和 AWS 區域。我們建議每個工作負載 AWS 帳戶 (或使用個別佈建的容量保留區) 執行一個工作負載,以防止工作負載競爭相同的配額。

如果您在相同的帳戶中執行兩個工作負載,其中一個工作負載可能要執行突增的查詢。這可能會導致剩餘的工作負載遭受限流或封鎖,而無法執行查詢。若要避免這種情況,您可以將工作負載移至不同的帳戶,以便為每個工作負載提供自己的並行配額。為一個或兩個工作負載建立佈建的容量保留可完成相同的目標。

其他服務的配額

當 Athena 執行查詢時,它可以呼叫其他強制執行配額的服務。在查詢執行期間,Athena 可以對 Amazon S3 和其他 AWS 服務 (例如 IAM 和 AWS KMS. AWS Glue Data Catalog如果您使用聯合查詢,Athena 也會致電 AWS Lambda。所有這些服務都有自己的限制和配額,可以超過。當查詢執行遇到來自這些服務的錯誤時,其便會失敗並包含來源服務的錯誤。重試可復原的錯誤,但如果問題無法及時自行解決,查詢仍可能失敗。請務必徹底閱讀錯誤訊息,以判斷其是來自 Athena 還是來自其他服務。本文件涵蓋了一些相關錯誤。

如需有關解決 Amazon S3 Service Quotas 造成的錯誤的資訊,請參閱本文件稍後的 避免檔案太多。如需有關 Amazon S3 效能最佳化的詳細資訊,請參閱《Amazon S3 使用者指南》中的最佳實務設計模式:最佳化 Amazon S3 效能

資源限制

Athena 會在分散式查詢引擎中執行查詢。當您提交查詢時,Athena 引擎查詢規劃程式會預估執行查詢所需的運算容量,並相應地準備運算節點叢集。某些查詢 (例如 DDL 查詢) 只在一個節點上執行。大型資料集的複雜查詢可在更大的叢集上執行。節點是統一的,具有相同的記憶體、CPU 和磁碟組態。Athena 透過橫向擴展 (而非向上擴展) 來處理要求更高的查詢。

有時候,查詢的需求會超過執行查詢的叢集的可用資源。發生這種情況時,查詢會失敗,並顯示錯誤在此擴展因數下查詢耗盡的資源

最常耗盡的資源是記憶體,但在極少數情況下,也可以是磁碟空間。當引擎執行聯結或視窗函數時,通常會發生記憶體錯誤,但也可能發生在不同的計數和彙總中。

即使查詢失敗並出現「資源不足」錯誤一次,當您再次執行時,其可能會成功。查詢執行不是確定性的。載入資料所花費時間以及如何在節點上分配中繼資料集等因素,可能會導致資源使用量不同。例如,假設一個查詢聯結兩個資料表,並且聯結條件的值分佈存在很大偏差。這樣的查詢在大多數時間都可以成功,但是當最常見的值最終由相同節點處理時,偶爾會失敗。

若要避免查詢超出可用資源,請使用本文件中提及的效能調校秘訣。具體而言,有關如何最佳化會耗盡可用資源之查詢的秘訣,請參閱 最佳化聯結最佳化視窗函數使用近似值最佳化查詢

查詢最佳化技術

使用本節中描述的查詢最佳化技術,可加快查詢執行速度,或做為 Athena 中超出資源限制的查詢解決方法。

最佳化聯結

在分散式查詢引擎中執行聯結的策略有很多。最常見的兩個是分散式雜湊聯結和具有複雜聯結條件的查詢。

分散式雜湊聯結

最常見的聯結類型使用對等比較做為聯結條件。Athena 以分散式雜湊聯結的形式執行此類聯結。

在分散式雜湊聯結中,引擎會從聯結的一側建置一個查詢表 (雜湊資料表)。這一側稱為建置端。建置端的記錄分散在多個節點上。每個節點為其子集建置一個查詢表。接著,聯結的另一端稱為探查端,會透過節點進行串流。探查端的記錄以與建置端相同的方式分散在節點上。這樣會啟用每個節點,以透過在其自己的查詢表中查詢相符記錄來執行聯結。

當從聯結的建置端建立的查詢表不適合放入記憶體中時,查詢可能會失敗。即使建置端的總大小小於可用記憶體,如果記錄的分佈存在很大偏差,查詢也可能會失敗。在極端情況下,所有記錄可能具有相同的聯結條件值,並且必須放入單一節點上的記憶體中。如果將一組值傳送至相同節點,且值加起來超過可用記憶體,即使是查詢偏差較小,也可能會失敗。節點確實可以將記錄溢寫至磁碟,但溢出會降低查詢執行速度,並且可能不足以防止查詢失敗。

Athena 會嘗試重新排序聯結,以使用較大的關係做為探查端,而較小的關係做為建置端。不過,由於 Athena 不會管理資料表中的資料,所以資訊有限,而且通常必須假設第一個資料表較大,第二個資料表較小。

使用以等值為基礎的聯結條件撰寫聯結時,假設 JOIN 關鍵字左側的資料表是探查端,右側的資料表是建置端。確保正確的資料表 (建置端) 是較小的資料表。如果無法使聯結的建置端足夠小以放入記憶體中,請考慮執行多個聯結建置資料表子集的查詢。

其他聯結類型

具有複雜聯結條件的查詢 (例如,使用 LIKE> 或其他運算子的查詢) 通常運算要求較高。在最壞的情況下,聯結一端的每條記錄必須與聯結另一端的每條記錄進行比較。由於執行時間會隨著記錄數量的平方而增加,因此此類查詢會有超過最大執行時間的風險。

若要了解 Athena 將如何事先執行查詢,您可以使用 EXPLAIN 陳述式。如需詳細資訊,請參閱 在 Athena 使用 EXPLAIN 和 EXPLAIN ANALYZE了解 Athena EXPLAIN 陳述式結果

最佳化視窗函數

由於視窗函數是資源密集型操作,所以它們可能會使查詢執行緩慢甚至失敗,並顯示在此擴展因數下查詢耗盡的資源。視窗函數將其操作的所有記錄保留在記憶體中,以便計算其結果。當視窗非常大時,視窗函數可能會耗盡記憶體。

為了確保您的查詢在可用的記憶體限制內執行,請減少視窗函數操作的視窗大小。為此,您可以新增 PARTITIONED BY 子句或縮小現有分割區子句的範圍。

改用非視窗函數

有時,具有視窗函數的查詢可以在沒有視窗函數的情況下重寫。例如,您可以使用 ORDER BYLIMIT,而不是使用 row_number 來尋找前 N 個記錄。您可以使用彙總函數 (例如 max_bymin_byarbitrary),而不是使用 row_numberrank 來重複記錄。

例如,假設您的資料集包含來自感應器的更新。感應器會定期報告其電池狀態,並包含一些中繼資料,例如位置。如果您想知道每個感應器及其位置的最新電池狀態,可以使用以下查詢:

SELECT sensor_id, arbitrary(location) AS location, max_by(battery_status, updated_at) AS battery_status FROM sensor_readings GROUP BY sensor_id

因為每筆記錄的中繼資料 (例如位置) 都相同,因此您可以使用 arbitrary 函數從群組中選擇任何值。

要獲取最新的電池狀態,您可以使用 max_by 函數。max_by 函數從找到另一個資料欄的最大值的記錄中選擇資料欄的值。在此範例中,它會傳回群組內上次更新時間的記錄的電池狀態。與具有視窗函數的對等查詢相比,此查詢執行速度更快,而且使用的記憶體更少。

最佳化彙總

當 Athena 執行彙總時,它會使用 GROUP BY 子句中的資料欄,跨不同的工作節點分佈記錄。為了使相符記錄與群組的任務盡可能有效率,節點會嘗試將記錄放入記憶體中,但必要時會將記錄溢寫至磁碟。

避免在 GROUP BY 子句中包含備援資料欄也是個不錯的主意。由於較少的資料欄需要較少的記憶體,因此使用較少資料欄描述群組的查詢會更有效率。數值資料欄使用的記憶體也少於字串。例如,當您彙總同時具有數值類別 ID 和類別名稱的資料集時,請僅使用 GROUP BY 子句中的類別 ID 資料欄。

有時候,查詢會在 GROUP BY 子句中包含資料欄,以解決資料欄必須是 GROUP BY 子句的一部分或彙總表達式的事實。如果未遵循此規則,您可能會收到以下錯誤訊息:

EXPRESSION_NOT_AGGREGATE:行 1:8:「類別」必須是一個彙總表達式或出現在 GROUP BY 子句

若要避免在 GROUP BY 子句中新增備援資料欄,您可以使用任意函數,如下列範例所示。

SELECT country_id, arbitrary(country_name) AS country_name, COUNT(*) AS city_count FROM world_cities GROUP BY country_id

ARBITRARY 函數會從群組中傳回任意值。當您知道群組中的所有記錄都具有相同的資料欄值,但該值無法識別群組時,此函數非常有用。

最佳化前 N 個查詢

ORDER BY 子句會以排序順序傳回查詢的結果。Athena 使用分散式排序,在多個節點上平行執行排序操作。

如果您並不需要對結果進行排序,請避免新增 ORDER BY 子句。另外,如果並非絕對必要,請避免新增 ORDER BY 到內部查詢。在許多情況下,查詢規劃程式可以移除備援排序,但不保證一定如此。此規則的例外是,如果內部查詢正在執行前 N 個操作,例如尋找最新的 N 個值或最常用的 N 個值。

當 Athena 發現 ORDER BYLIMIT 時,就會明白您正在執行前 N 個查詢,並相應地使用專用操作。

注意

雖然 Athena 也經常可以偵測視窗函數 (例如使用前 N 個的 row_number),但我們建議使用 ORDER BYLIMIT 的較簡單版本。如需詳細資訊,請參閱 最佳化視窗函數

僅包含必填資料欄

如果您並不需要資料欄,請不要將其包含在查詢中。查詢必須處理的資料越少,執行速度就越快。這可以減少所需的記憶體數量,以及必須在節點之間傳送的資料量。如果您使用的是單欄式檔案格式,減少資料欄數量也會減少從 Amazon S3 讀取的資料量。

Athena 對結果中的資料欄數量沒有特定限制,但是執行查詢的方式會限制可能的資料欄合併大小。資料欄的合併大小包括它們的名稱和類型。

例如,下列錯誤是由超出關係描述項大小限制的關係造成的:

一般 _ 內部錯誤:.airlift. 位元組碼。 CompilationException

若要解決此問題,請減少查詢中的資料欄數量或建立子查詢,並使用擷取較少量資料的 JOIN。如果您有在最外層查詢中執行 SELECT * 的查詢,則應將 * 變更為僅包含所需資料欄的清單。

使用近似值最佳化查詢

Athena 支援近似彙總函數,用於計算獨特值、最常出現的值、百分位數 (包括近似中位數),以及建立直方圖。每當不需要確切值時,請使用這些函數。

COUNT(DISTINCT col) 操作不同,approx_distinct 使用的記憶體更少且執行速度更快。同樣,使用 numeric_histogram (而不是直方圖) 使用了近似方法,因此所需的記憶體更少。

最佳化 LIKE

您可以使用 LIKE 來查找相符字串,但對於長字串而言,此為計算密集型。regexp_like 函數在大多數情況下是一個更快的替代方案,並且還提供了更多的靈活性。

通常,您可以透過錨定要尋找的子字串來最佳化搜尋。例如,如果您正在尋找字首,最好使用 'substr%' 而不是 '%substr%'。或者,如果您使用的是 regexp_like,則為 '^substr'。

使用 UNION ALL 而非 UNION

UNION ALLUNION 是兩種將兩個查詢結果合併為一個結果的方法。UNION ALL 將第一個查詢中的記錄與第二個查詢中的記錄串連起來,且 UNION 會執行相同的操作,但也會移除重複項目。UNION 需要處理所有記錄並找到重複項目,此為記憶體和計算密集型,不過 UNION ALL 是一個相對快速的操作。除非您需要重複記錄,否則請使用 UNION ALL 以獲得最佳效能。

對大型結果集使用 UNLOAD

當查詢結果預期很大 (例如,數萬個資料列或更多) 時,請使用 UNLOAD 匯出結果。在大多數情況下,這比執行規則查詢更快,並且使用 UNLOAD 也可以讓您更好地控制輸出。

查詢完成執行後,Athena 會將結果以單一未壓縮的 CSV 檔案形式存放在 Amazon S3 上。這比 UNLOAD 需要更長的時間,不僅因為結果未壓縮,而且還因為操作無法平行化。相反地,UNLOAD 會直接從工作節點寫入結果,並充分利用運算叢集的平行處理。此外,您可以設定 UNLOAD,以壓縮格式和其他檔案格式 (例如 JSON 和 Parquet) 寫入結果。

如需詳細資訊,請參閱 UNLOAD

使用 CTAS 或 Glue ETL 將常用的彙總具體化

「具體化」查詢是一種透過儲存預先計算的複雜查詢結果 (例如,彙總和聯結) 以便在後續查詢中重複使用,來加速查詢效能的方法。

如果您的許多查詢包含相同的聯結和彙總,您可以將通用子查詢具體化為新資料表,然後針對該資料表執行查詢。您可以使用 從查詢結果建立資料表 (CTAS) 或專用 ETL 工具 (例如 Glue ETL) 來建立新的資料表。

例如,假設您的儀表板中包含顯示訂單資料集的不同層面的小工具。每個小工具都有自己的查詢,但所有查詢會共用相同的聯結和篩選條件。訂單資料表會與明細項目資料表結合在一起,而且有一個篩選條件,可僅顯示過去三個月。如果您識別這些查詢的常用功能,您可以建立小工具可使用的新資料表。這樣可以減少重複並提高效能。缺點是您必須將資料表保持在最新狀態。

重複使用查詢結果

同一查詢在短時間內執行多次非常常見。例如,當多個人開啟相同的資料儀表板時,就會發生這種情況。執行查詢時,您可以告訴 Athena 重複使用先前計算的結果。您可以指定要重複使用的結果的最長期限。如果先前在該時間範圍內執行同一查詢,Athena 會傳回這些結果,而不是再次執行查詢。如需詳細資訊,請參閱此處《Amazon Athena 使用者指南》中的 重複使用查詢結果,以及 AWS 大數據部落格中的使用 Amazon Athena 查詢結果重複使用降低成本和提升查詢效能

資料最佳化技術

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

分割您的資料

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

選擇將支援您查詢的分割區索引鍵

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

避免最佳化罕見查詢

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

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

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

使用分割區投影

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

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

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

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

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

如需有關分割區投影的詳細資訊,請參閱使用 Amazon Athena 進行分割區投影

使用分割區索引

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

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

就像關聯式資料庫一樣,您可以透過新增索引來提高查詢的效能。您可以新增多個索引,以支援不同的查詢模式。資料 AWS Glue Data Catalog 分割索引支援相等運算子和比較運算子>,例如>=、,並與運AND算子<結合。如需詳細資訊,請參閱開AWS Glue 發人員指南 AWS Glue中的使用分割區索引AWS 大數據部落格中的使用 AWS Glue Data Catalog 分區索引改善 Amazon Athena 查詢效能

始終使用 STRING 做為分割區索引鍵類型

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

移除舊的和空的分割區

如果您從 Amazon S3 上的分割區移除資料 (例如,使用 Amazon S3 生命週期),您也應該從 AWS Glue Data Catalog中移除分割區項目。在查詢規劃期間,與查詢相符的任何分割區都會列在 Amazon S3 上。如果您有許多空的分割區,列出這些分割區的負荷可能會產生不利影響。

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

依等式查詢分割區

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

如果無法重寫查詢以透過等式篩選分割區,則可以嘗試分割區投影。如需詳細資訊,請參閱 使用分割區投影

避免使用 MSCK REPAIR TABLE 進行分割區維護

由於 MSCK REPAIR TABLE 可能需要很長的時間才能執行,並且僅會新增分割區,而不會移除舊的分割區,因此不是管理分割區的有效方法 (請參閱 考量與限制)。

使用 AWS Glue Data Catalog APIALTER TABLE ADD PARTITIONAWS Glue 爬蟲程式可以更好地手動管理分割區。或者,您也可以使用分割區投影,這樣就不需要完全管理分割區。如需詳細資訊,請參閱 使用 Amazon Athena 進行分割區投影

驗證您的查詢是否與分割結構相容

您可以使用 EXPLAIN 陳述式預先檢查查詢將掃描的分割區。使用 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 陳述式結果

使用單欄式檔案格式

專為分散式分析工作負載而設計的單欄式檔案格式,例如 Parquet 和 ORC。它們依資料欄而非資料列整理資料。以單欄式格式整理資料具有下列優點:

  • 僅會載入查詢所需的資料欄

  • 減少需要載入的整體資料量

  • 資料欄值會一起存放,因此可以有效地壓縮資料

  • 檔案可以包含允許引擎略過載入不需要的資料的中繼資料

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

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

使用單欄式檔案格式時,請確定檔案不會太小。如 避免檔案太多 中所述,含有許多小型檔案的資料集會造成效能問題。對於單欄式檔案格式而言,尤其如此。對於小型檔案,單欄式檔案格式的負荷超過優勢。

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

若要將其他資料格式轉換為鑲木地板或 ORC,您可以使用 AWS Glue ETL 或 Athena。如需有關使用 Athena for ETL 的詳細資訊,請參閱 使用 CTAS 和 INSERT INTO 以進行 ETL 和資料分析

壓縮資料

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

gzip 格式提供了良好的壓縮比,並且在其他工具和服務中具有廣泛的支援。zstd (Zstandard) 格式是一種較新的壓縮格式,可使效能和壓縮比之間達到良好的平衡。

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

避免檔案太多 中所述,檔案最好不要太多也不宜過少。由於檔案數目是可處理查詢的工作者數量限制,因此對於壓縮檔案而言,此規則尤其如此。

如需有關在 Athena 中使用壓縮的詳細資訊,請參閱 Athena 壓縮支援

使用歸納來查詢具有高基數的索引鍵

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

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

歸納的缺點

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

如需詳細資訊,請參閱 在 Athena 中分割和歸納

避免檔案太多

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

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

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

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

SlowDown:請降低您的請求率

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

如果執行單一查詢觸發錯誤,請嘗試合併資料檔案或修改查詢,以讀取較少的檔案。合併小型檔案的最佳時間是在將其寫入之前。為此,請考慮下列技巧:

避免分割區以外的其他儲存體階層

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

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

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

僅在必要時使用 SymlinkTextInputFormat

使用 SymlinkTextInputFormat 技術可以是一種解決相關情況的方法,當資料表的檔案沒有整齊地整理到分割區中時。例如,當所有檔案都使用相同的字首,或是具有不同結構描述的檔案位於相同位置時,符號連結可能很有用。

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

其他資源

如需 Athena 效能調校的其他相關資訊,請參閱下列資源: