本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
查詢計劃
您可以使用查詢計畫來取得執行查詢所需的個別操作的相關資訊。使用查詢計畫之前,建議您先了解 Amazon Redshift 如何處理處理中的查詢和建立查詢計畫。如需詳細資訊,請參閱 查詢計劃和執行工作流程。
若要建立查詢計畫,請執行 EXPLAIN 命令,後面接著實際的查詢文字。查詢計畫可提供下列資訊:
-
執行引擎將執行的操作,請由下至上閱讀結果。
-
每個操作會執行的步驟類型。
-
每個操作中使用的資料表和資料欄。
-
每個操作中處理的資料量,就資料列的數量和資料寬度 (位元組) 而言。
-
操作的相對成本。成本是一種測量方式,會比較計畫內步驟的相對執行時間。成本不會提供實際執行時間或記憶體消耗的任何精確資訊,也不會提供執行計畫之間有意義的比較。但它可提供您查詢中耗費最多資源的操作的指示。
EXPLAIN 命令不會實際執行查詢。它只會顯示如果查詢是在目前操作條件下執行時,Amazon Redshift 會執行的計畫。如果您變更資料表的結構描述或資料,並再次執行 ANALYZE 以更新統計資訊中繼資料,查詢計畫可能不同。
EXPLAIN 的查詢計畫輸出為查詢執行的簡化、高階檢視。它不會說明平行查詢處理的詳細資訊。若要查看詳細資訊,請執行查詢本身,然後從 SVL_QUERY_SUMMARY 或 SVL_QUERY_REPORT 檢視取得查詢摘要資訊。如需使用這些檢視的相關資訊,請參閱分析查詢摘要。
下列範例顯示 EVENT 資料表上簡易 GROUP BY 查詢的 EXPLAIN 輸出:
explain select eventname, count(*) from event group by eventname; QUERY PLAN ------------------------------------------------------------------- XN HashAggregate (cost=131.97..133.41 rows=576 width=17) -> XN Seq Scan on event (cost=0.00..87.98 rows=8798 width=17)
EXPLAIN 會傳回每個操作的下列指標:
- 費用
-
用在計畫內比較操作的相對值。成本由兩個小數值組成,以兩個句點分隔,例如
cost=131.97..133.41
。第一個值,在此情況下的 131.97,提供傳回此操作第一個資料列的相對成本。第二個值,在此情況下的 133.41,提供完成操作的相對成本。當您讀取計劃時,查詢計劃中的成本是累計的,因此此範例中的 HashAggregate 成本 (131.97.. 133.41) 會包含其下方的「序號掃描」成本 (0.00.. 87.98)。 - 資料列
-
要傳回的估計資料列數量。在此範例中,掃描預期傳回 8798 個資料列。 HashAggregate 運算子本身預期會傳回 576 列 (在結果集中捨棄重複的事件名稱之後)。
注意
資料列估計是根據 ANALYZE 命令產生的可用統計資料。如果最近未執行 ANALYZE,估計將較不可靠。
- 寬度
-
估計的平均資料列寬度 (位元組)。在此範例中,平均資料列的寬度預期為 17 個位元組。
EXPLAIN 運算子
此小節簡要描述您最常在 EXPLAIN 輸出中看見的運算子。如需運算子的完整清單,請參閱 SQL 命令小節中的 EXPLAIN。
循序掃描運算子
循序掃描運算子 (Seq Scan) 指出資料表掃描。Seq Scan 會從開頭到結尾循序掃描資料表中的每個資料欄,並評估每個資料列的查詢限制條件 (在 WHERE 子句中)。
聯結運算子
Amazon Redshift 會根據要聯結資料表的實體設計、聯結所需的位置資料,以及查詢本身的特定需求來選取聯結運算子。
-
巢狀迴路
最差的最佳聯結,巢狀迴路主要用於交叉聯結 (笛卡兒乘積) 和一些對等聯結中。
-
雜湊聯結和雜湊
雜湊聯結和雜湊通常會較巢狀迴路聯結更快速,用於內部聯結和左右外部聯結。當聯結資料表中的聯結資料欄不是散發索引鍵也不是排序索引鍵時,會使用這些運算子。雜湊運算子會為聯結中的內部資料表建立雜湊表;雜湊聯結運算子會讀取外部資料表、雜湊聯結資料欄,並在內部雜湊表中尋找相符項目。
-
合併聯結
合併聯結通常是最快速的聯結,用於內部聯結和外部聯結。合併聯結不會用於完整聯結。當聯結資料表中的聯結資料欄為散發索引鍵也是排序索引鍵,並且少於 20% 的聯結資料表未排序時,會使用此運算子。它會依序讀取兩個排序的資料表,並尋找相符的資料列。若要檢視未排序資料列的百分比,請查詢 SVV_TABLE_INFO 系統資料表。
-
空間聯結
通常基於空間資料的鄰近程度快速聯結,用於
GEOMETRY
和GEOGRAPHY
資料類型。
彙整運算子
查詢計畫會在牽涉到彙整函數和 GROUP BY 操作的查詢中使用下列運算子。
-
Aggregate
純量彙整函數的運算子,例如 AVG 和 SUM。
-
HashAggregate
未排序的分組彙整函數的運算子。
-
GroupAggregate
排序的分組彙整函數的運算子。
排序運算子
查詢計畫會在查詢必須排序或合併結果集時使用下列運算子。
-
排序
評估 ORDER BY 子句和其他排序操作,例如 UNION 查詢和聯結、SELECT DISTINCT 查詢和視窗函數要求的排序。
-
合併
根據衍生自平行操作中繼排序的結果,產生最終排序的結果。
UNION、INTERSECT 和 EXCEPT 運算子
查詢計畫會對牽涉到 UNION、INTERSECT 和 EXCEPT 設定操作的查詢使用下列運算子。
-
Subquery
用來執行 UNION 查詢。
-
Hash Intersect Distinct
用來執行 INTERSECT 查詢。
-
SetOp 除外
用來執行 EXCEPT (或 MINUS) 查詢。
其他運算子
下列運算子也會經常出現在例行查詢的 EXPLAIN 輸出中。
-
唯一
消除 SELECT DISTINCT 查詢和 UNION 查詢的重複項目。
-
限制
處理 LIMIT 子句。
-
視窗
執行視窗函數。
-
結果
執行未牽涉任何資料表存取的純量函數。
-
Subplan
用於特定子查詢。
-
網路
將中繼結果傳送至領導者節點供進一步處理。
-
Materialize
儲存資料列以輸入至巢狀迴路聯結和一些合併聯結。
EXPLAIN 中的聯結
取決於查詢和基礎資料表的結構,查詢最佳化器會使用不同的聯結類型來擷取資料表資料。EXPLAIN 輸出會參考聯結類型、使用的資料表,以及資料表資料在叢集間配送的方式,以描述查詢的處理方式。
聯結類型範例
下列範例顯示查詢最佳化器可以使用的不同聯結類型。查詢計畫中使用的聯結類型取決於所牽涉資料表的實體設計。
範例:雜湊聯結兩個資料表
下列查詢會聯結 CATID 資料欄上的 EVENT 和 CATEGORY。CATID 為 CATEGORY (但不是 EVENT) 的配送和排序索引鍵。執行雜湊聯結,EVENT 為外部資料表而 CATEGORY 為內部資料表。因為 CATEGORY 為較小的資料表,規劃器會在查詢處理期間透過使用 DS_BCAST_INNER 播送其一份副本至運算節點。此範例中的聯結成本可說明計畫的多數累積成本。
explain select * from category, event where category.catid=event.catid; QUERY PLAN ------------------------------------------------------------------------- XN Hash Join DS_BCAST_INNER (cost=0.14..6600286.07 rows=8798 width=84) Hash Cond: ("outer".catid = "inner".catid) -> XN Seq Scan on event (cost=0.00..87.98 rows=8798 width=35) -> XN Hash (cost=0.11..0.11 rows=11 width=49) -> XN Seq Scan on category (cost=0.00..0.11 rows=11 width=49)
注意
EXPLAIN 輸出中運算子的對應縮排有時會指出那些操作並非彼此相依,因此可以平行開始。在前述範例中,EVENT 資料表上的掃描雖然已與雜湊操作對應,EVENT 掃描仍必須等候雜湊操作已完全完成為止。
範例:合併聯結兩個資料表
下列查詢也使用 SELECT *,但它會聯結 LISTID 資料欄上的 SALES 和 LISTING,其中的 LISTID 已設為這兩個資料表的配送和排序索引鍵。已選擇合併聯結,並且聯結 (DS_DIST_NONE) 不需要重新配送資料。
explain select * from sales, listing where sales.listid = listing.listid; QUERY PLAN ----------------------------------------------------------------------------- XN Merge Join DS_DIST_NONE (cost=0.00..6285.93 rows=172456 width=97) Merge Cond: ("outer".listid = "inner".listid) -> XN Seq Scan on listing (cost=0.00..1924.97 rows=192497 width=44) -> XN Seq Scan on sales (cost=0.00..1724.56 rows=172456 width=53)
下列範例示範相同查詢內不同類型的聯結。在上一個範例中,SALES 和 LISTING 已合併聯結,但第三個資料表 EVENT 必須與合併聯結的結果雜湊聯結。重申,雜湊聯結會衍生播送成本。
explain select * from sales, listing, event where sales.listid = listing.listid and sales.eventid = event.eventid; QUERY PLAN ---------------------------------------------------------------------------- XN Hash Join DS_BCAST_INNER (cost=109.98..3871130276.17 rows=172456 width=132) Hash Cond: ("outer".eventid = "inner".eventid) -> XN Merge Join DS_DIST_NONE (cost=0.00..6285.93 rows=172456 width=97) Merge Cond: ("outer".listid = "inner".listid) -> XN Seq Scan on listing (cost=0.00..1924.97 rows=192497 width=44) -> XN Seq Scan on sales (cost=0.00..1724.56 rows=172456 width=53) -> XN Hash (cost=87.98..87.98 rows=8798 width=35) -> XN Seq Scan on event (cost=0.00..87.98 rows=8798 width=35)
範例:聯結、彙整和排序
下列查詢會執行 SALES 和 EVENT 資料表的雜湊聯結,接著彙整和排序操作以說明分組的 SUM 函數和 ORDER BY 子句。初始的排序運算子會在運算節點上平行執行。然後 Network 運算子會傳送結果至領導者節點,在其中,Merge 運算子會產生最終排序的結果。
explain select eventname, sum(pricepaid) from sales, event where sales.eventid=event.eventid group by eventname order by 2 desc; QUERY PLAN --------------------------------------------------------------------------------- XN Merge (cost=1002815366604.92..1002815366606.36 rows=576 width=27) Merge Key: sum(sales.pricepaid) -> XN Network (cost=1002815366604.92..1002815366606.36 rows=576 width=27) Send to leader -> XN Sort (cost=1002815366604.92..1002815366606.36 rows=576 width=27) Sort Key: sum(sales.pricepaid) -> XN HashAggregate (cost=2815366577.07..2815366578.51 rows=576 width=27) -> XN Hash Join DS_BCAST_INNER (cost=109.98..2815365714.80 rows=172456 width=27) Hash Cond: ("outer".eventid = "inner".eventid) -> XN Seq Scan on sales (cost=0.00..1724.56 rows=172456 width=14) -> XN Hash (cost=87.98..87.98 rows=8798 width=21) -> XN Seq Scan on event (cost=0.00..87.98 rows=8798 width=21)
資料重新分佈
聯結的 EXPLAIN 輸出也可為在叢集間移動資料的方式指定可輔助聯結的方法。資料可以透過播送或重新配送來移動。在播送中,來自聯結一端的資料值會從每個運算節點複製到每個其他運算節點,使得每個運算節點最終有完整的資料副本。在重新配送中,參與的資料值是從其目前的配量傳送至新配量 (可能在不同的節點上)。資料一般會重新配送以符合參與聯結的其他資料表的散發索引鍵 (如果該散發索引鍵是其中一個聯結資料欄)。如果任何資料表都不具備其中一個聯結資料欄上的散發索引鍵,則會配送兩個資料表,或是將內部資料表播送至每個節點。
EXPLAIN 輸出也會參考內部和外部資料表。會先掃描內部資料表,並出現在較接近查詢計畫底端的位置。內部資料表為對其探測相符項目的資料表。它通常位於記憶體中,且通常是雜湊的來源資料表,如有可能,會是要聯結的兩個資料表中較小的那個。外部資料表為要對內部資料表比對的資料列的來源。通常是從磁碟讀取。查詢最佳化器會根據來自 ANALYZE 命令最近一次執行的資料庫統計資料來選擇內部和外部資料表。查詢的 FROM 子句中資料表的順序,並不會決定哪個資料表為內部以及哪個為外部。
請在查詢計畫中使用下列屬性來識別資料將移動的方式,以輔助查詢:
-
DS_BCAST_INNER
將整個內部資料表的副本播送至所有運算節點。
-
DS_DIST_ALL_NONE
不需要重新配送,因為已使用 DISTSTYLE ALL 將內部資料表配送至每個節點。
-
DS_DIST_NONE
不重新配送任何資料表。共置聯結可行,因為會聯結對應的配量,而不需在節點間移動資料。
-
DS_DIST_INNER
重新配送內部資料表。
-
DS_DIST_OUTER
重新配送外部資料表。
-
DS_DIST_ALL_INNER
因為外部資料表使用 DISTSTYLE ALL,會將整個內部資料表重新配送至單一配量。
-
DS_DIST_BOTH
重新配送這兩個資料表。