

 Amazon Redshift 將不再支援從修補程式 198 開始建立新的 Python UDFs。現有 Python UDF 將繼續正常運作至 2026 年 6 月 30 日。如需詳細資訊，請參閱[部落格文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

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

# 調校查詢效能
<a name="c-optimizing-query-performance"></a>

Amazon Redshift 使用基於結構化查詢語言 (SQL) 的查詢來與系統中的資料與物件互動。資料處理語言 (DML) 是 SQL 的子集，您它用來檢視、新增、變更和刪除資料。資料定義語言 (DDL) 是 SQL 的子集，您用它來新增、變更和刪除資料庫物件 (例如：資料表和檢視表)。

設定系統之後，通常您最常使用的會是 DML，尤其是使用 [SELECT](r_SELECT_synopsis.md) 命令來擷取和檢視資料。若要在 Amazon Redshift 中編寫有效的資料擷取查詢，請熟悉 SELECT 語法，並套用[設計資料表的 Amazon Redshift 最佳實務](c_designing-tables-best-practices.md)中所述的秘訣，將查詢的效率盡量放大。

若要了解 Amazon Redshift 如何處理查詢，請使用[查詢處理](c-query-processing.md)和[查詢分析和改善](c-query-tuning.md)小節。然後您可以套用此資訊結合診斷工具來識別和消除查詢效能中的問題。

若要識別和解決使用 Amazon Redshift 查詢時可能遇到的部分最常見和最嚴重的問題，請使用[查詢故障診斷](queries-troubleshooting.md)小節。

**Topics**
+ [查詢處理](c-query-processing.md)
+ [查詢分析和改善](c-query-tuning.md)
+ [查詢故障診斷](queries-troubleshooting.md)

# 查詢處理
<a name="c-query-processing"></a>

Amazon Redshift 會透過剖析器和最佳化器遞送提交的 SQL 查詢，以開發查詢計畫。執行引擎接著會將查詢計畫轉譯為程式碼，並將該程式碼傳送至運算節點以供執行。

**Topics**
+ [查詢計劃和執行工作流程](c-query-planning.md)
+ [建立和解譯查詢計畫](c-the-query-plan.md)
+ [檢閱查詢計劃步驟](reviewing-query-plan-steps.md)
+ [影響查詢效能的因素](c-query-performance.md)

# 查詢計劃和執行工作流程
<a name="c-query-planning"></a>

下表提供查詢計畫和執行工作流程的整體檢視。

![\[領導節點的查詢規劃和執行工作流程。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/07-QueryPlanning.png)


查詢計畫和執行工作流程會遵循這些步驟：

1. 領導者節點接收查詢並剖析 SQL。

1. 剖析器會產生初始查詢樹狀目錄，它是原始查詢的邏輯呈現。然後，Amazon Redshift 會將此查詢樹狀目錄輸入至查詢最佳化器。

1. 最佳化器會進行評估，並且在必要時重新編寫查詢以最佳化其效率。此程序有時會造成建立多個相關的查詢來取代單一查詢。

1. 最佳化器會產生一個查詢計畫 (或數個，如果先前的步驟產生多個查詢) 以利用最佳效能執行。查詢計畫會指定執行選項，例如：聯結類型、聯結順序、彙整選項和資料配送需求。

   您可以使用 [EXPLAIN](r_EXPLAIN.md) 命令來檢視查詢計畫。查詢計畫為用於分析和調校複雜查詢的基礎工具。如需詳細資訊，請參閱[建立和解譯查詢計畫](c-the-query-plan.md)。

1. 執行引擎會將查詢計畫轉譯為*步驟*、*區段*和*串流*：  
**步驟**  
每個步驟為查詢執行期間所需的個別操作。您可以結合步驟，以允許運算節點執行查詢、聯結或其他資料庫操作。  
**區段**  
可以透過單一程序完成的數個步驟組合，也是可由運算節點配量執行的最小的編譯單位。*配量*是 Amazon Redshift 中平行處理的單位。串流中的區段會平行執行。  
**串流**  
要透過可用運算節點配量打包的區段的集合。

   執行引擎會根據步驟、區段和串流產生編譯的程式碼。相較於轉譯的程式碼，編譯的程式碼執行得更快速，並且使用較少運算容量。然後將此編譯的程式碼播送至運算節點。
**注意**  
設定查詢的基準時，應該一律比較查詢的第二個執行的時間，因為第一個執行時間包含編譯程式碼的間接。如需詳細資訊，請參閱[影響查詢效能的因素](c-query-performance.md)。

1. 運算節點配量會平行執行查詢區段。隨著此程序，Amazon Redshift 會利用最佳化的網路通訊、記憶體和磁碟管理，在查詢計畫步驟之間傳遞中繼結果。這也有助於加快查詢執行速度。

步驟 5 和 6 會對每個串流發生一次。引擎會為一個串流建立可執行的區段，並將它們傳送至運算節點。當該串流的區段完成時，引擎會產生下一個串流的區段。以此方式，引擎可以分析前一個串流中發生的動作 (例如，操作是否基於磁碟) 以影響下一個串流中區段的產生。

當運算節點完成時，它們會將查詢結果傳回至領導者節點供最終處理。領導者節點會將資料合併至單一結果集，並解決任何需要的排序或彙整。然後領導者節點會將結果傳回至用戶端。

**注意**  
在查詢執行期間，運算節點可能會在必要時傳回一些資料至領導者節點。例如，如果您的子查詢具有 LIMIT 子句，則會於資料在叢集間重新配送供進一步處理之前，將限制套用到領導者節點。

# 建立和解譯查詢計畫
<a name="c-the-query-plan"></a>

您可以使用查詢計畫來取得執行查詢所需的個別操作的相關資訊。使用查詢計畫之前，建議您先了解 Amazon Redshift 如何處理處理中的查詢和建立查詢計畫。如需詳細資訊，請參閱[查詢計劃和執行工作流程](c-query-planning.md)。

若要建立查詢計畫，請執行 [EXPLAIN](r_EXPLAIN.md) 命令，後面接著實際的查詢文字。查詢計畫可提供下列資訊：
+ 執行引擎將執行的操作，請由下至上閱讀結果。
+ 每個操作會執行的步驟類型。
+ 每個操作中使用的資料表和資料欄。
+ 每個操作中處理的資料量，就資料列的數量和資料寬度 (位元組) 而言。
+ 操作的相對成本。*成本*是一種測量方式，會比較計畫內步驟的相對執行時間。成本不會提供實際執行時間或記憶體消耗的任何精確資訊，也不會提供執行計畫之間有意義的比較。但它可提供您查詢中耗費最多資源的操作的指示。

EXPLAIN 命令不會實際執行查詢。它只會顯示如果查詢是在目前操作條件下執行時，Amazon Redshift 會執行的計畫。如果您變更資料表的結構描述或資料，並再次執行 [ANALYZE](r_ANALYZE.md) 以更新統計資訊中繼資料，查詢計畫可能不同。

EXPLAIN 的查詢計畫輸出為查詢執行的簡化、高階檢視。它不會說明平行查詢處理的詳細資訊。若要查看詳細資訊，請執行查詢本身，然後從 SVL\$1QUERY\$1SUMMARY 或 SVL\$1QUERY\$1REPORT 檢視取得查詢摘要資訊。如需使用這些檢視的相關資訊，請參閱[分析查詢摘要](c-analyzing-the-query-summary.md)。

下列範例顯示 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**  
用在計畫內比較操作的相對值。成本由兩個小數值組成，以兩個句點分隔，例如 `cost=131.97..133.41`。第一個值，在此情況下的 131.97，提供傳回此操作第一個資料列的相對成本。第二個值，在此情況下的 133.41，提供完成操作的相對成本。查詢計畫中的成本會隨著您往上讀取計畫而累積，使得此範例中的 HashAggregate 成本 (131.97..133.41) 包含的 Seq Scan 成本 (0.00..87.98) 較它低。

**資料列**  
要傳回的估計資料列數量。在此範例中，掃描預期傳回 8798 個資料列。HashAggregate 運算子本身預期傳回 576 個資料列 (複製之後，會從結果集捨棄事件名稱)。  
資料列估計是根據 ANALYZE 命令產生的可用統計資料。如果最近未執行 ANALYZE，估計將較不可靠。

**Width**  
估計的平均資料列寬度 (位元組)。在此範例中，平均資料列的寬度預期為 17 個位元組。

## EXPLAIN 運算子
<a name="EXPLAIN-operators"></a>

此小節簡要描述您最常在 EXPLAIN 輸出中看見的運算子。如需運算子的完整清單，請參閱 SQL 命令小節中的 [EXPLAIN](r_EXPLAIN.md)。

### 循序掃描運算子
<a name="scan-operator"></a>

循序掃描運算子 (Seq Scan) 指出資料表掃描。Seq Scan 會從開頭到結尾循序掃描資料表中的每個資料欄，並評估每個資料列的查詢限制條件 (在 WHERE 子句中)。

### 聯結運算子
<a name="join-operators"></a>

Amazon Redshift 會根據要聯結資料表的實體設計、聯結所需的位置資料，以及查詢本身的特定需求來選取聯結運算子。
+ **巢狀迴路**

  最差的最佳聯結，巢狀迴路主要用於交叉聯結 (笛卡兒乘積) 和一些對等聯結中。
+ **雜湊聯結和雜湊**

  雜湊聯結和雜湊通常會較巢狀迴路聯結更快速，用於內部聯結和左右外部聯結。當聯結資料表中的聯結資料欄不是散發索引鍵*也不是*排序索引鍵時，會使用這些運算子。雜湊運算子會為聯結中的內部資料表建立雜湊表；雜湊聯結運算子會讀取外部資料表、雜湊聯結資料欄，並在內部雜湊表中尋找相符項目。
+ **合併聯結**

  合併聯結通常是最快速的聯結，用於內部聯結和外部聯結。合併聯結不會用於完整聯結。當聯結資料表中的聯結資料欄為散發索引鍵*也是*排序索引鍵，並且少於 20% 的聯結資料表未排序時，會使用此運算子。它會依序讀取兩個排序的資料表，並尋找相符的資料列。若要檢視未排序資料列的百分比，請查詢 [SVV\$1TABLE\$1INFO](r_SVV_TABLE_INFO.md) 系統資料表。
+ **空間聯結**

  通常基於空間資料的鄰近程度快速聯結，用於 `GEOMETRY` 和 `GEOGRAPHY` 資料類型。

### 彙整運算子
<a name="aggregate-operators"></a>

查詢計畫會在牽涉到彙整函數和 GROUP BY 操作的查詢中使用下列運算子。
+ **Aggregate**

  純量彙整函數的運算子，例如 AVG 和 SUM。
+ **HashAggregate**

  未排序的分組彙整函數的運算子。
+ **GroupAggregate**

  排序的分組彙整函數的運算子。

### 排序運算子
<a name="sort-operators"></a>

查詢計畫會在查詢必須排序或合併結果集時使用下列運算子。
+ **排序**

  評估 ORDER BY 子句和其他排序操作，例如 UNION 查詢和聯結、SELECT DISTINCT 查詢和視窗函數要求的排序。
+ **合併**

  根據衍生自平行操作中繼排序的結果，產生最終排序的結果。

### UNION、INTERSECT 和 EXCEPT 運算子
<a name="UNION-INTERSECT-and-EXCEPT-operators"></a>

查詢計畫會對牽涉到 UNION、INTERSECT 和 EXCEPT 設定操作的查詢使用下列運算子。
+ **Subquery**

  用來執行 UNION 查詢。
+ **Hash Intersect Distinct **

  用來執行 INTERSECT 查詢。
+ **SetOp Except**

  用來執行 EXCEPT (或 MINUS) 查詢。

### 其他運算子
<a name="other-operators"></a>

下列運算子也會經常出現在例行查詢的 EXPLAIN 輸出中。
+ **唯一**

  消除 SELECT DISTINCT 查詢和 UNION 查詢的重複項目。
+ **限制**

  處理 LIMIT 子句。
+ **視窗**

  執行視窗函數。
+ **結果**

  執行未牽涉任何資料表存取的純量函數。
+ **Subplan**

  用於特定子查詢。
+ **網路**

  將中繼結果傳送至領導者節點供進一步處理。
+ **Materialize**

  儲存資料列以輸入至巢狀迴路聯結和一些合併聯結。

## EXPLAIN 中的聯結
<a name="joins-in-EXPLAIN"></a>

取決於查詢和基礎資料表的結構，查詢最佳化器會使用不同的聯結類型來擷取資料表資料。EXPLAIN 輸出會參考聯結類型、使用的資料表，以及資料表資料在叢集間配送的方式，以描述查詢的處理方式。

### 聯結類型範例
<a name="join-types"></a>

下列範例顯示查詢最佳化器可以使用的不同聯結類型。查詢計畫中使用的聯結類型取決於所牽涉資料表的實體設計。

#### 範例：雜湊聯結兩個資料表
<a name="hash-join-two-tables"></a>

下列查詢會聯結 CATID 資料欄上的 EVENT 和 CATEGORY。CATID 為 CATEGORY (但不是 EVENT) 的配送和排序索引鍵。執行雜湊聯結，EVENT 為外部資料表而 CATEGORY 為內部資料表。因為 CATEGORY 為較小的資料表，規劃器會在查詢處理期間透過使用 DS\$1BCAST\$1INNER 播送其一份副本至運算節點。此範例中的聯結成本可說明計畫的多數累積成本。

```
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 掃描仍必須等候雜湊操作已完全完成為止。

#### 範例：合併聯結兩個資料表
<a name="merge-join-two-tables"></a>

下列查詢也使用 SELECT \$1，但它會聯結 LISTID 資料欄上的 SALES 和 LISTING，其中的 LISTID 已設為這兩個資料表的配送和排序索引鍵。已選擇合併聯結，並且聯結 (DS\$1DIST\$1NONE) 不需要重新配送資料。

```
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)
```

#### 範例：聯結、彙整和排序
<a name="join-aggregate-and-sort-example"></a>

下列查詢會執行 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)
```

### 資料重新分佈
<a name="data-redistribution"></a>

聯結的 EXPLAIN 輸出也可為在叢集間移動資料的方式指定可輔助聯結的方法。資料可以透過播送或重新配送來移動。在播送中，來自聯結一端的資料值會從每個運算節點複製到每個其他運算節點，使得每個運算節點最終有完整的資料副本。在重新配送中，參與的資料值是從其目前的配量傳送至新配量 (可能在不同的節點上)。資料一般會重新配送以符合參與聯結的其他資料表的散發索引鍵 (如果該散發索引鍵是其中一個聯結資料欄)。如果任何資料表都不具備其中一個聯結資料欄上的散發索引鍵，則會配送兩個資料表，或是將內部資料表播送至每個節點。

EXPLAIN 輸出也會參考內部和外部資料表。會先掃描內部資料表，並出現在較接近查詢計畫底端的位置。內部資料表為對其探測相符項目的資料表。它通常位於記憶體中，且通常是雜湊的來源資料表，如有可能，會是要聯結的兩個資料表中較小的那個。外部資料表為要對內部資料表比對的資料列的來源。通常是從磁碟讀取。查詢最佳化器會根據來自 ANALYZE 命令最近一次執行的資料庫統計資料來選擇內部和外部資料表。查詢的 FROM 子句中資料表的順序，並不會決定哪個資料表為內部以及哪個為外部。

請在查詢計畫中使用下列屬性來識別資料將移動的方式，以輔助查詢：
+ **DS\$1BCAST\$1INNER**

  將整個內部資料表的副本播送至所有運算節點。
+ **DS\$1DIST\$1ALL\$1NONE**

  不需要重新配送，因為已使用 DISTSTYLE ALL 將內部資料表配送至每個節點。
+ **DS\$1DIST\$1NONE**

  不重新配送任何資料表。共置聯結可行，因為會聯結對應的配量，而不需在節點間移動資料。
+ **DS\$1DIST\$1INNER**

  重新配送內部資料表。
+ **DS\$1DIST\$1OUTER**

  重新配送外部資料表。
+ **DS\$1DIST\$1ALL\$1INNER**

  因為外部資料表使用 DISTSTYLE ALL，會將整個內部資料表重新配送至單一配量。
+ **DS\$1DIST\$1BOTH**

  重新配送這兩個資料表。

# 檢閱查詢計劃步驟
<a name="reviewing-query-plan-steps"></a>

您可以執行 EXPLAIN 命令來查看查詢計畫中的步驟。下列範例顯示 SQL 查詢並說明輸出。您可以由下至上閱讀查詢計畫，以查看用於執行查詢的每個邏輯操作。如需詳細資訊，請參閱[建立和解譯查詢計畫](c-the-query-plan.md)。

```
explain
select eventname, sum(pricepaid) from sales, event
where sales.eventid = event.eventid
group by eventname
order by 2 desc;
```

```
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)
```

在產生查詢計畫的過程中，查詢最佳化工具會將計畫劃分為串流、區段和步驟。查詢最佳化工具會細分計畫，以準備將資料和查詢工作負載分配到運算節點。如需串流、區段和步驟的相關資訊，請參閱[查詢計劃和執行工作流程](c-query-planning.md)。

下圖顯示先前的查詢和相關聯的查詢計畫。其顯示涉及的查詢操作如何映射至 Amazon Redshift 用於為運算節點配量產生編譯程式碼的步驟。每個查詢計畫操作會映射至區段內的多個步驟，並且有時映射至串流內的多個區段。

![\[對應至三個串流的查詢及其相關聯的查詢計畫。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/map-plan-to-streams.png)


在此圖中，查詢最佳化工具會執行查詢計畫，如下所示：

1. 在 `Stream 0` 中，查詢會以循序掃描操作執行 `Segment 0`，以掃描 `events` 資料表。查詢會使用雜湊操作繼續處理 `Segment 1`，為聯結中的內部資料表建立雜湊表。

1. 在 `Stream 1` 中，查詢會以循序掃描操作執行 `Segment 2`，以掃描 `sales` 資料表。它會使用雜湊連結繼續處理 `Segment 2`，以聯結含有不是散發索引鍵也不是排序索引鍵之聯結資料欄的資料表。它會再次使用雜湊彙總繼續處理 `Segment 2`，以彙總結果。然後查詢會執行 `Segment 3` 搭配雜湊彙總操作，以執行未排序的分組彙總函數和排序操作，進而評估 ORDER BY 子句和其他排序操作。

1. 在 `Stream 2` 中，查詢會在 `Segment 4` 和 `Segment 5` 中執行網路操作，以將中繼結果傳送到領導節點進一步處理。

查詢的最後一個區段會傳回資料。如果傳回集合已彙總或排序，則運算節點會各自將其中繼結果部分傳送到領導節點。領導節點會接著合併資料，以便將最終結果送回給請求的用戶端。

如需 EXPLAIN 運算子的相關資訊，請參閱 [EXPLAIN](r_EXPLAIN.md)。

# 影響查詢效能的因素
<a name="c-query-performance"></a>

有一些因素會影響查詢效能。您的資料、叢集和資料庫操作的下列層面，都會影響處理查詢的速度。
+ **節點、處理器或配量的數量** – 運算節點會分割為配量。更多節點表示更多處理器和更多配量，透過在配量間並行執行部分的查詢，可讓您的查詢處理得更快速。不過，更多節點也表示更大的開支，因此必須尋找適合您的系統的成本與效能的平衡點。如需 Amazon Redshift 叢集架構的相關資訊，請參閱[資料倉儲系統架構](c_high_level_system_architecture.md)。
+ **節點類型** - Amazon Redshift 叢集可以使用數種節點類型之一。每個節點類型可提供不同的大小和限制，以幫助您適當地調整叢集的規模。節點大小會決定叢集中每個節點的儲存容量、記憶體、CPU 和價格。如需節點類型的相關資訊，請參閱《Amazon Redshift 管理指南》**中的 [Amazon Redshift 叢集概觀](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html#working-with-clusters-overview)。
+ **資料配送** – Amazon Redshift 會根據資料表的配送樣式，將資料表資料儲存在運算節點。當您執行查詢時，查詢最佳化器會視需要將資料重新配送至運算節點，以執行任何聯結與彙整。選擇資料表的適當配送樣式，有助於降低重新配送步驟所帶來的影響，方法是在執行聯結之前，將資料放置在需要的位置。如需詳細資訊，請參閱[分配資料以實現查詢最佳化](t_Distributing_data.md)。
+ **資料排序排列** – Amazon Redshift 會根據資料表的排序索引鍵，以排序的順序將資料表資料儲存在磁碟上。查詢最佳化器和查詢處理器使用資料所在位置的資訊以減少必須掃描的區塊數量，藉以改善查詢速度。如需詳細資訊，請參閱[排序索引鍵](t_Sorting_data.md)。
+ **資料集大小** – 由於需要掃描和重新配送更多資料列，因此叢集中較多的資料量可能拖慢查詢的查詢效能。您可以透過定期清空和封存資料，以及使用述詞來限制查詢資料集，藉以減緩此影響。
+ **並行操作** – 一次執行多個操作可能影響查詢效能。每個操作會使用可用查詢佇列中的一或多個位置，並使用與那些位置關聯的記憶體。如果其他操作正在執行，則可能沒有足夠的查詢佇列位置可供使用。在此情況下，查詢必須等候位置開放之後才可以開始處理。如需建立和設定查詢佇列的相關資訊，請參閱[工作負載管理](cm-c-implementing-workload-management.md)。
+ **查詢結構** – 寫入查詢的方式會影響其效能。請對程序寫入盡可能多的查詢，並傳回符合您需求的最少資料。如需詳細資訊，請參閱[設計查詢的 Amazon Redshift 最佳實務](c_designing-queries-best-practices.md)。
+ **程式碼編譯** – Amazon Redshift 會為每個查詢執行計畫產生和編譯最佳化程式碼。編譯的程式碼執行速度更快，因為它消除了使用解譯器的額外負荷。為了將新查詢的延遲降至最低，同時保留編譯程式碼的效能優勢，Amazon Redshift 使用稱為合成的技術。合成會產生預先存在邏輯的輕量型配置，以立即處理新查詢，同時在背景編譯高度最佳化的查詢特定程式碼。這會從查詢執行的關鍵路徑移除編譯，因此新查詢的啟動速度更快，並提供與後續執行一致的效能。

  Amazon Redshift 也會使用無伺服器編譯服務，將查詢編譯擴展到 Amazon Redshift 叢集的運算資源之外。編譯的程式碼區段會在本機快取在叢集上，並在叢集重新啟動後持續存在的幾乎無限制的遠端快取中。相同查詢的後續執行可以加快執行速度，因為它可以略過編譯階段。透過使用可擴展的編譯服務，Amazon Redshift 會平行編譯程式碼，以提供一致的快速效能。

# 查詢分析和改善
<a name="c-query-tuning"></a>

從 Amazon Redshift 資料倉儲擷取資訊需要對非常大量的資料執行複雜的查詢，這可能耗費冗長時間來處理。若要確保盡可能快速處理查詢，有一些工具可供您用來識別潛在的效能問題。

**Topics**
+ [查詢分析工作流程](c-query-analysis-process.md)
+ [檢閱查詢提醒](c-reviewing-query-alerts.md)
+ [分析查詢計劃](c-analyzing-the-query-plan.md)
+ [分析查詢摘要](c-analyzing-the-query-summary.md)
+ [查詢效能改善](query-performance-improvement-opportunities.md)
+ [診斷查詢以進行查詢調校](diagnostic-queries-for-query-tuning.md)

# 查詢分析工作流程
<a name="c-query-analysis-process"></a>

如果查詢耗費的時間超過預期，請使用下列步驟來識別並更正可能對查詢效能帶來負面影響的問題。如果您不確定系統中有哪些查詢可能透過效能調校而獲益，請在[識別用於調校的最高候選項目查詢](identify-queries-that-are-top-candidates-for-tuning.md)中執行診斷查詢以開始。

1. 確定您的資料表是根據最佳實務而設計。如需詳細資訊，請參閱[設計資料表的 Amazon Redshift 最佳實務](c_designing-tables-best-practices.md)。

1. 請查看是否可以刪除或封存資料表中任何不需要的資料。例如，假設您的查詢一律鎖定最近 6 個月的資料量，但是您的資料表中有最近 18 個月的資料。在此情況下，您可以刪除或封存較舊的資料，以減少需要掃描和配送的記錄數量。

1. 在查詢中對資料表執行 [VACUUM](r_VACUUM_command.md) 命令，以回收空間和重新排序資料列。如果未排序的區域很大，並且查詢使用聯結或述詞中的排序索引鍵，則執行 VACUUM 有幫助。

1. 在查詢中對資料表執行 [ANALYZE](r_ANALYZE.md) 命令，以確定統計資料是最新的。如果查詢中任何資料表的大小最近有許多變更，則執行 ANALYZE 很有幫助。如果執行完整的 ANALYZE 命令將耗費太長時間，請對單一資料欄執行分析以減少處理時間。此方法仍會更新資料表大小統計資料；資料表大小是查詢計畫中的顯著因素。

1. 確定您的查詢已對每個類型的用戶端執行一次 (根據用戶端使用的連線通訊協定的類型而定)，使得該查詢會經過編譯和快取。這種方法會加速查詢的後續執行。如需詳細資訊，請參閱[影響查詢效能的因素](c-query-performance.md)。

1. 請檢查[STL\$1ALERT\$1EVENT\$1LOG](r_STL_ALERT_EVENT_LOG.md)資料表來識別和更正您的查詢的可能問題。如需詳細資訊，請參閱[檢閱查詢提醒](c-reviewing-query-alerts.md)。

1. 執行 [EXPLAIN](r_EXPLAIN.md) 命令來取得查詢計畫，並用它來最佳化查詢。如需詳細資訊，請參閱[分析查詢計劃](c-analyzing-the-query-plan.md)。

1. 使用[SVL\$1QUERY\$1SUMMARY](r_SVL_QUERY_SUMMARY.md)和[SVL\$1QUERY\$1REPORT](r_SVL_QUERY_REPORT.md)檢視來取得摘要資訊，並用它來最佳化查詢。如需詳細資訊，請參閱[分析查詢摘要](c-analyzing-the-query-summary.md)。

有時應該快速執行的查詢會被強制等候其他長時間執行的查詢完成。在該情況下，對於查詢本身，您可能沒有可改善的項目，但您可以藉由對不同類型的查詢建立和使用查詢佇列來改善整體系統效能。若要獲得您的查詢佇列等候時間的概念，請參閱[檢閱查詢的佇列等候時間](review-queue-wait-times-for-queries.md)。如需設定查詢佇列的相關資訊，請參閱[工作負載管理](cm-c-implementing-workload-management.md)。

# 檢閱查詢提醒
<a name="c-reviewing-query-alerts"></a>

若要使用[STL\$1ALERT\$1EVENT\$1LOG](r_STL_ALERT_EVENT_LOG.md)系統資料表來識別和更正您的查詢的潛在效能問題，請遵循這些步驟：

1. 執行下列動作來判斷您的查詢 ID：

   ```
   select query, elapsed, substring
   from svl_qlog
   order by query
   desc limit 5;
   ```

   在 `substring` 欄位中檢查截斷的查詢文字，判斷要選取的 `query` 值。如果您已執行查詢超過一次，請使用來自具有較低 `query` 值資料列的 `elapsed` 值。那是編譯版本的資料列。如果您已執行許多查詢，您可以提升 LIMIT 子句使用的值，以確定您的查詢已包含在其中。

1. 從 STL\$1ALERT\$1EVENT\$1LOG 中，為您的查詢選取資料列：

   ```
   Select * from stl_alert_event_log where query = MyQueryID;               
   ```  
![\[STL_ALERT_EVENT_LOG 的範例查詢結果。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/stl_alert_event_log_results.png)

1. 評估您的查詢的結果。使用下表來找出任何遇到問題的潛在解決方案。
**注意**  
STL\$1ALERT\$1EVENT\$1LOG 中不會有所有查詢的資料列，只有已發現問題的那些查詢。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/c-reviewing-query-alerts.html)

# 分析查詢計劃
<a name="c-analyzing-the-query-plan"></a>

執行 [EXPLAIN](r_EXPLAIN.md) 命令來取得查詢計畫。

分析查詢計畫之前，您應該熟悉如何閱讀它。如果您對於閱讀查詢計畫不熟悉，建議您閱讀[建立和解譯查詢計畫](c-the-query-plan.md)之後再繼續。

若要分析查詢計畫提供的資料，請遵循這些步驟：

1. 識別具有最高成本的步驟。繼續進行其餘步驟時，請專注在那些。

1. 查看聯結類型：
   + **巢狀迴路**：這類聯結的發生通常是因為省略了聯結條件。如需建議的解決方案，請參閱[巢狀迴圈](query-performance-improvement-opportunities.md#nested-loop)。
   + **雜湊和雜湊聯結**：當聯結資料表中的聯結資料欄不是散發索引鍵也不是排序索引鍵時，會使用雜湊聯結。如需建議的解決方案，請參閱[雜湊聯結](query-performance-improvement-opportunities.md#hash-join)。
   + **合併聯結**：不需變更。

1. 注意哪個資料表用於內部聯結，以及哪個用於外部聯結。查詢引擎一般會對內部聯結選擇較小的資料表，以及對外部聯結選擇較大的資料表。如果這類選擇未發生，那麼，您的統計資料很可能過時。如需建議的解決方案，請參閱[資料表統計資訊遺漏或過時](query-performance-improvement-opportunities.md#table-statistics-missing-or-out-of-date)。

1. 查看是否有任何高成本的排序操作。如果有，請參閱[未排序或排序錯誤的資料列](query-performance-improvement-opportunities.md#unsorted-or-mis-sorted-rows)以取得建議的解決方案。

1. 尋找具有高成本操作的下列播送運算子：
   + **DS\$1BCAST\$1INNER**：表示資料表已廣播至所有運算節點。這對於小資料表來說很好，但對於較大的資料表來說並不理想。
   + **DS\$1DIST\$1ALL\$1INNER**：指出所有工作負載位於單一配量上。
   + **DS\$1DIST\$1BOTH**：指出繁重的重新配送。

   如需這些情況的建議解決方案，請參閱[次佳資料分佈](query-performance-improvement-opportunities.md#suboptimal-data-distribution)。

# 分析查詢摘要
<a name="c-analyzing-the-query-summary"></a>

若要取得較 [EXPLAIN](r_EXPLAIN.md) 所產生的查詢計畫更詳細的執行步驟和統計資料，請使用 [SVL\$1QUERY\$1SUMMARY](r_SVL_QUERY_SUMMARY.md) 和 [SVL\$1QUERY\$1REPORT](r_SVL_QUERY_REPORT.md) 系統檢視。

SVL\$1QUERY\$1SUMMARY 提供依串流的查詢統計資料。您可以使用其提供的資訊來識別具有代價高昂步驟、長時間執行步驟和寫入磁碟步驟的問題。

SVL\$1QUERY\$1REPORT 系統檢視可用來查看與 SVL\$1QUERY\$1SUMMARY 類似的資訊，但只能依運算節點配量而不能依串流查看。您可以使用配量層級資訊來偵測叢集間不平均的資料配送 (也稱為資料配送偏度)，它會強制部分節點執行較其他節點更多的工作，並影響查詢效能。

**Topics**
+ [使用 SVL\$1QUERY\$1SUMMARY 檢視](using-SVL-Query-Summary.md)
+ [使用 SVL\$1QUERY\$1REPORT 檢視](using-SVL-Query-Report.md)
+ [將查詢計劃映射到查詢摘要](query-plan-summary-map.md)

# 使用 SVL\$1QUERY\$1SUMMARY 檢視
<a name="using-SVL-Query-Summary"></a>

若要使用 [SVL\$1QUERY\$1SUMMARY](r_SVL_QUERY_SUMMARY.md) 依串流分析摘要資訊，請執行下列操作：

1. 執行下列查詢來判斷您的查詢 ID：

   ```
   select query, elapsed, substring
   from svl_qlog
   order by query
   desc limit 5;
   ```

   在 `substring` 欄位中檢查截斷的查詢文字，判斷代表您的查詢的 `query` 值。如果您已執行查詢超過一次，請使用來自具有較低 `query` 值資料列的 `elapsed` 值。那是編譯版本的資料列。如果您已執行許多查詢，您可以提升 LIMIT 子句使用的值，以確定您的查詢已包含在其中。

1. 從 SVL\$1QUERY\$1SUMMARY 中，為您的查詢選取資料列。依串流、區段和步驟排列結果：

   ```
   select * from svl_query_summary where query = MyQueryID order by stm, seg, step;
   ```

   以下是結果範例。  
![\[SVL_QUERY_SUMMARY 中符合特定查詢之列的範例結果。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/svl_query_summary_results.png)

1. 使用[將查詢計劃映射到查詢摘要](query-plan-summary-map.md)中的資訊，將步驟與查詢計畫中的操作映射。它們的資料列和位元組應該具有大約相同的值 (查詢計畫中的資料列 \$1 寬度)。如果不同，請參閱[資料表統計資訊遺漏或過時](query-performance-improvement-opportunities.md#table-statistics-missing-or-out-of-date)以取得建議的解決方案。

1. 查看任何步驟的 `is_diskbased` 欄位是否具有 `t` (true) 值。如果系統沒有為查詢處理配置足夠的記憶體，雜湊、彙整和排序為可能將資料寫入至磁碟的運算子。

   如果 `is_diskbased` 為 true，請參閱[配置給查詢的記憶體不足](query-performance-improvement-opportunities.md#insufficient-memory-allocated-to-the-query)以取得建議的解決方案。

1. 檢閱 `label` 欄位值，並查看步驟中的任何位置是否有 AGG-DIST-AGG 序列。出現它表示兩個步驟彙整，其代價高昂。若要修正此問題，請將 GROUP BY 子句變更為使用散發索引鍵 (如果有多個則第一個索引鍵)。

1. 檢閱每個區段的 `maxtime` 值 (區段中的所有步驟是相同的)。識別具有最高 `maxtime` 值的區段，並檢閱此區段中下列運算子的步驟。
**注意**  
高的 `maxtime` 值並不一定代表區段有問題。雖然值很高，但該區段可能並未耗費大量時間處理。串流中的所有區段會同時開始計時。不過，部分下游區段必須等到取得來自上游的資料後才能執行。此影響可能使得它們看起來耗費了長時間，因為其 `maxtime` 值將同時包含等候時間和處理時間。
   + **BCAST 或 DIST**：在這些情況下，造成 `maxtime` 高值的原因可能是重新配送大量資料列。如需建議的解決方案，請參閱[次佳資料分佈](query-performance-improvement-opportunities.md#suboptimal-data-distribution)。
   + **HJOIN (雜湊聯結)**：如果有問題步驟的 `rows` 欄位相較於查詢中最終 RETURN 步驟中的 `rows` 值有非常高的值，請參閱[雜湊聯結](query-performance-improvement-opportunities.md#hash-join)以取得建議的解決方案。
   + **SCAN/SORT**：在聯結步驟之前尋找步驟的 SCAN、SORT、SCAN、MERGE 序列。這個模式指出未排序的資料會經過掃描、排序，然後與資料表排序的區域合併。

     查看相較於查詢中最終 RETURN 步驟的資料列值，SCAN 步驟的資料列值是否有非常高的值。這個模式指出執行引擎正在掃描稍後將捨棄的資料列，這樣做缺乏效率。如需建議的解決方案，請參閱[不足的限制性述詞](query-performance-improvement-opportunities.md#insufficiently-restrictive-predicate)。

     如果 SCAN 步驟的 `maxtime` 值很高，請參閱[次佳的 WHERE 子句](query-performance-improvement-opportunities.md#suboptimal-WHERE-clause)以取得建議的解決方案。

     如果 SORT 步驟的 `rows` 值不是零，請參閱[未排序或排序錯誤的資料列](query-performance-improvement-opportunities.md#unsorted-or-mis-sorted-rows)以取得建議的解決方案。

1. 檢閱最終 RETURN 步驟之前的 5–10 步驟的 `rows` 和 `bytes` 值，來了解傳回用戶端的資料量。此程序可以是一門藝術。

   例如，在下列範例查詢摘要中，第三個 PROJECT 步驟提供 `rows` 值而非 `bytes` 值。查看前述步驟來找到具有相同 `rows` 值的步驟，您會找到同時提供列和位元組資訊的 SCAN 步驟。

    以下是範例結果。  
![\[查詢摘要結果中的列，這是同時包含列和位元組資訊的 SCAN 步驟。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/rows_and_bytes.png)

   如果您要傳回異常大的資料量，請參閱[非常大的結果集](query-performance-improvement-opportunities.md#very-large-result-set)以取得建議的解決方案。

1. 相較於其他步驟，查看 `bytes` 值是否相對於任何步驟中的 `rows` 值來得高。這個模式可能指出您正選取許多資料欄。如需建議的解決方案，請參閱[大型 SELECT 清單](query-performance-improvement-opportunities.md#large-SELECT-list)。

# 使用 SVL\$1QUERY\$1REPORT 檢視
<a name="using-SVL-Query-Report"></a>

若要使用 [SVL\$1QUERY\$1REPORT](r_SVL_QUERY_REPORT.md) 依切片分析摘要資訊，請執行下列操作：

1. 執行下列動作來判斷您的查詢 ID：

   ```
   select query, elapsed, substring
   from svl_qlog
   order by query
   desc limit 5;
   ```

   在 `substring` 欄位中檢查截斷的查詢文字，判斷代表您的查詢的 `query` 值。如果您已執行查詢超過一次，請使用來自具有較低 `query` 值資料列的 `elapsed` 值。那是編譯版本的資料列。如果您已執行許多查詢，您可以提升 LIMIT 子句使用的值，以確定您的查詢已包含在其中。

1. 從 SVL\$1QUERY\$1REPORT 中，為您的查詢選取資料列。依區段、步驟、經過時間和資料列排列結果：

   ```
   select * from svl_query_report where query = MyQueryID order by segment, step, elapsed_time, rows;
   ```

1. 針對每個步驟，查看所有配量是否正處理大約相同數量的資料列：  
![\[用來執行查詢的資料切片清單。每個切片會處理大致相同的列數。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/SVL_QUERY_REPORT_rows.png)

   也查看所有配量是否正耗費大約相同的時間量：  
![\[用來執行查詢的資料切片清單。每個切片所花費的時間大致相同。\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/images/SVL_QUERY_REPORT_elapsed_time.png)

   這些值的差異大可能表示由於此特定查詢的次佳配送樣式造成的資料配送偏度。如需建議的解決方案，請參閱[次佳資料分佈](query-performance-improvement-opportunities.md#suboptimal-data-distribution)。

# 將查詢計劃映射到查詢摘要
<a name="query-plan-summary-map"></a>

分析查詢摘要時，您可以藉由將查詢計畫中的操作對應至查詢摘要中的步驟 (以標籤欄位值識別)，以取得更多詳細資訊。下表將查詢計畫操作對應至查詢摘要步驟。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/redshift/latest/dg/query-plan-summary-map.html)

# 查詢效能改善
<a name="query-performance-improvement-opportunities"></a>

以下是影響 Amazon Redshift 查詢效能的一些常見問題，以及其診斷和解決方式的指示。

**Topics**
+ [資料表統計資訊遺漏或過時](#table-statistics-missing-or-out-of-date)
+ [巢狀迴圈](#nested-loop)
+ [雜湊聯結](#hash-join)
+ [幽靈資料列或未遞交的資料列](#ghost-rows-or-uncommitted-rows)
+ [未排序或排序錯誤的資料列](#unsorted-or-mis-sorted-rows)
+ [次佳資料分佈](#suboptimal-data-distribution)
+ [配置給查詢的記憶體不足](#insufficient-memory-allocated-to-the-query)
+ [次佳的 WHERE 子句](#suboptimal-WHERE-clause)
+ [不足的限制性述詞](#insufficiently-restrictive-predicate)
+ [非常大的結果集](#very-large-result-set)
+ [大型 SELECT 清單](#large-SELECT-list)

## 資料表統計資訊遺漏或過時
<a name="table-statistics-missing-or-out-of-date"></a>

如果資料表統計資料遺漏或過時，您可能會看見下列：
+ EXPLAIN 命令結果中有警告訊息。
+ STL\$1ALERT\$1EVENT\$1LOG 中遺漏統計資料提醒事件。如需詳細資訊，請參閱[檢閱查詢提醒](c-reviewing-query-alerts.md)。

若要修正此問題，請執行 [ANALYZE](r_ANALYZE.md)。

## 巢狀迴圈
<a name="nested-loop"></a>

如果出現巢狀迴路，您可能會在 STL\$1ALERT\$1EVENT\$1LOG 中看見巢狀迴路提醒事件。您也可以透過執行[識別具有巢狀迴圈的查詢](identify-queries-with-nested-loops.md)中的查詢，來識別此類型的事件。如需詳細資訊，請參閱[檢閱查詢提醒](c-reviewing-query-alerts.md)。

若要修正此問題，請檢閱您的查詢以取得交叉聯結並在可能時加以移除。交叉聯結是沒有聯結條件的聯結，會造成兩個資料表的笛卡兒乘積。它們通常會以巢狀迴圈聯結的形式執行，這是可能的聯結類型中最慢的。

## 雜湊聯結
<a name="hash-join"></a>

如果出現雜湊聯結，您可能會看見下列：
+ 查詢計畫中的雜湊和雜湊聯結操作。如需詳細資訊，請參閱[分析查詢計劃](c-analyzing-the-query-plan.md)。
+ 區段中的 HJOIN 步驟具有 SVL\$1QUERY\$1SUMMARY 中最高的 maxtime 值。如需詳細資訊，請參閱[使用 SVL\$1QUERY\$1SUMMARY 檢視](using-SVL-Query-Summary.md)。

若要修正此問題，您可以採取兩個方法：
+ 如果可能，重新寫入查詢以使用合併聯結。指定同時為散發索引鍵和排序索引鍵的聯結資料欄即可執行此動作。
+ 如果 SVL\$1QUERY\$1SUMMARY 的 HJOIN 步驟的資料列欄位相較於查詢中最終 RETURN 步驟中的資料列值有非常高的值，請檢查您是否可以重新寫入查詢以在唯一資料欄上聯結。當查詢未在唯一資料欄上聯結時，例如主要索引鍵，它會增加聯結中牽涉的資料列數量。

## 幽靈資料列或未遞交的資料列
<a name="ghost-rows-or-uncommitted-rows"></a>

如果出現幽靈資料列或未遞交的資料列，您可能會在 STL\$1ALERT\$1EVENT\$1LOG 看見提醒事件，指出過量的幽靈資料列。如需詳細資訊，請參閱[檢閱查詢提醒](c-reviewing-query-alerts.md)。

若要修正此問題，您可以採取兩個方法：
+ 查看 Amazon Redshift 主控台的**載入**索引標籤，以瞭解任何查詢資料表上的作用中載入操作。如果您看見作用中的載入操作，採取動作之前，請等候那些操作完成。
+ 如果沒有作用中載入操作，請在查詢資料表上執行 [VACUUM](r_VACUUM_command.md) 來移除刪除的資料列。

## 未排序或排序錯誤的資料列
<a name="unsorted-or-mis-sorted-rows"></a>

如果出現未排序或排序錯誤的資料列，您可能會在 STL\$1ALERT\$1EVENT\$1LOG 中看見非常高的篩選條件提醒事件。如需詳細資訊，請參閱[檢閱查詢提醒](c-reviewing-query-alerts.md)。

您也可以透過執行 [識別具有資料扭曲或未排序資料列的資料表](identify-tables-with-data-skew-or-unsorted-rows.md) 中的查詢，查看您的查詢中是否任何資料表有大型未排序的區域。

若要修正此問題，您可以採取兩個方法：
+ 在查詢資料表上執行 [VACUUM](r_VACUUM_command.md) 來重新排序資料列。
+ 檢閱查詢資料表上的排序索引鍵，以查看是否有可以進行的任何改善。請記得評估此查詢的效能與其他重要查詢和整體系統的效能，再進行任何變更。如需詳細資訊，請參閱[排序索引鍵](t_Sorting_data.md)。

## 次佳資料分佈
<a name="suboptimal-data-distribution"></a>

如果資料配送為次佳，您可能會看見下列：
+ STL\$1ALERT\$1EVENT\$1LOG 中出現序列執行、大型播送或大型配送提醒事件。如需詳細資訊，請參閱[檢閱查詢提醒](c-reviewing-query-alerts.md)。
+ 針對指定步驟，配量未處理大約相同數量的資料列。如需詳細資訊，請參閱[使用 SVL\$1QUERY\$1REPORT 檢視](using-SVL-Query-Report.md)。
+ 針對指定步驟，配量未耗費大約相同的時間量。如需詳細資訊，請參閱[使用 SVL\$1QUERY\$1REPORT 檢視](using-SVL-Query-Report.md)。

如果前述中無一成立，您也可以透過執行 [識別具有資料扭曲或未排序資料列的資料表](identify-tables-with-data-skew-or-unsorted-rows.md) 中的查詢，查看您的查詢中是否有任何資料表有資料偏度。

若要修正此問題，查看查詢中資料表的分佈樣式，並確認是否可以進行任何改善。請記得評估此查詢的效能與其他重要查詢和整體系統的效能，再進行任何變更。如需詳細資訊，請參閱[分配資料以實現查詢最佳化](t_Distributing_data.md)。

## 配置給查詢的記憶體不足
<a name="insufficient-memory-allocated-to-the-query"></a>

如果對您的查詢配置了不足的記憶體，您可能會在 SVL\$1QUERY\$1SUMMARY 中看見某個步驟的 `is_diskbased` 值為 true。如需詳細資訊，請參閱[使用 SVL\$1QUERY\$1SUMMARY 檢視](using-SVL-Query-Summary.md)。

若要修正此問題，請透過暫時增加它所使用查詢位置的數量，為查詢配置更多記憶體。工作負載管理 (WLM) 會在查詢佇列中預留位置，大約等同於為佇列設定的並行層級。例如，具有並行層級 5 的佇列有 5 個位置。指派給佇列的記憶體會平均配置到每個位置。對一個查詢指派數個位置可讓該查詢存取所有那些位置的記憶體。如需如何暫時增加查詢位置的相關資訊，請參閱[wlm\$1query\$1slot\$1count](r_wlm_query_slot_count.md)。

## 次佳的 WHERE 子句
<a name="suboptimal-WHERE-clause"></a>

如果您的 WHERE 子句造成過度的資料表掃描，您可能會在 SVL\$1QUERY\$1SUMMARY 中具有最高 `maxtime` 值的區段中看見 SCAN 步驟。如需詳細資訊，請參閱[使用 SVL\$1QUERY\$1SUMMARY 檢視](using-SVL-Query-Summary.md)。

若要修正此問題，請根據最大資料表的主要排序資料欄，將 WHERE 子句新增至查詢。這種方法可縮短降低掃描時間。如需詳細資訊，請參閱[設計資料表的 Amazon Redshift 最佳實務](c_designing-tables-best-practices.md)。

## 不足的限制性述詞
<a name="insufficiently-restrictive-predicate"></a>

如果您的查詢有不足的限制性述詞，您可能會在 SVL\$1QUERY\$1SUMMARY 中具有最高 `maxtime` 值的區段中看見 SCAN 步驟，其相較於查詢中最終 RETURN 步驟中的 `rows` 值具有非常高的 `rows` 值。如需詳細資訊，請參閱[使用 SVL\$1QUERY\$1SUMMARY 檢視](using-SVL-Query-Summary.md)。

若要修正此問題，請嘗試新增述詞至查詢，或讓現有述詞更具限制性來縮小列輸出。

## 非常大的結果集
<a name="very-large-result-set"></a>

如果您的查詢傳回非常大的結果集，請考慮重新寫入查詢，以使用 [UNLOAD](r_UNLOAD.md) 來寫入結果至 Amazon S3。此方式藉由利用平行處理，有效改善 RETURN 步驟的效能。如需檢查非常大型結果集的相關資訊，請參閱[使用 SVL\$1QUERY\$1SUMMARY 檢視](using-SVL-Query-Summary.md)。

## 大型 SELECT 清單
<a name="large-SELECT-list"></a>

如果您的查詢有異常大的 SELECT 清單，您可能會在 SVL\$1QUERY\$1SUMMARY 中看見相對於 (相較於其他步驟) 任何步驟的 `bytes` 值來得高的 `rows` 值。這個高 `bytes` 值可能是您正選取許多資料欄的指標。如需詳細資訊，請參閱[使用 SVL\$1QUERY\$1SUMMARY 檢視](using-SVL-Query-Summary.md)。

若要修正此問題，請檢閱您要選取的資料欄，並查看是否可移除任何項目。

# 診斷查詢以進行查詢調校
<a name="diagnostic-queries-for-query-tuning"></a>

使用下列查詢來識別查詢的問題或可能影響查詢效能的基礎資料表。建議您使用這些查詢結合[查詢分析和改善](c-query-tuning.md)中討論的查詢調校程序。

**注意**  
這些查詢適用於 Amazon Redshift 佈建叢集。這些查詢不適用於 Redshift Serverless 工作群組。

**Topics**
+ [識別用於調校的最高候選項目查詢](identify-queries-that-are-top-candidates-for-tuning.md)
+ [識別具有資料扭曲或未排序資料列的資料表](identify-tables-with-data-skew-or-unsorted-rows.md)
+ [識別具有巢狀迴圈的查詢](identify-queries-with-nested-loops.md)
+ [檢閱查詢的佇列等候時間](review-queue-wait-times-for-queries.md)
+ [依資料表檢閱查詢提醒](review-query-alerts-by-table.md)
+ [識別具有遺漏統計資訊的資料表](identify-tables-with-missing-statistics.md)

# 識別用於調校的最高候選項目查詢
<a name="identify-queries-that-are-top-candidates-for-tuning"></a>

下列查詢會識別過去 7 天中已執行的前 50 個最耗時的陳述式。您可以使用結果來識別需要異常長時間的查詢。您也可以識別經常執行的查詢 (在結果集中出現超過一次的項目)。這些查詢往往是進行調校以改善系統效能的良好候選項目。

此查詢也提供與所識別的每個查詢關聯的提醒事件計數。這些提醒提供的詳細資訊可供您用來改善查詢的效能。如需詳細資訊，請參閱[檢閱查詢提醒](c-reviewing-query-alerts.md)。

```
select trim(database) as db, count(query) as n_qry, 
max(substring (qrytext,1,80)) as qrytext, 
min(run_minutes) as "min" , 
max(run_minutes) as "max", 
avg(run_minutes) as "avg", sum(run_minutes) as total,  
max(query) as max_query_id, 
max(starttime)::date as last_run, 
sum(alerts) as alerts, aborted
from (select userid, label, stl_query.query, 
trim(database) as database, 
trim(querytxt) as qrytext, 
md5(trim(querytxt)) as qry_md5, 
starttime, endtime, 
(datediff(seconds, starttime,endtime)::numeric(12,2))/60 as run_minutes,     
alrt.num_events as alerts, aborted 
from stl_query 
left outer join 
(select query, 1 as num_events from stl_alert_event_log group by query ) as alrt 
on alrt.query = stl_query.query
where userid <> 1 and starttime >=  dateadd(day, -7, current_date)) 
group by database, label, qry_md5, aborted
order by total desc limit 50;
```

# 識別具有資料扭曲或未排序資料列的資料表
<a name="identify-tables-with-data-skew-or-unsorted-rows"></a>

下列查詢會識別具有不均資料配送 (資料偏度) 或高比例未排序資料列的資料表。

低的 `skew` 值指出資料表資料已正確配送。如果資料表有 4.00 或更高的 `skew` 值，請考慮修改其資料配送樣式。如需詳細資訊，請參閱[次佳資料分佈](query-performance-improvement-opportunities.md#suboptimal-data-distribution)。

如果資料表的 `pct_unsorted` 值大於 20%，請考慮執行 [VACUUM](r_VACUUM_command.md) 命令。如需詳細資訊，請參閱[未排序或排序錯誤的資料列](query-performance-improvement-opportunities.md#unsorted-or-mis-sorted-rows)。

同時另外檢閱每個資料表的 `mbytes` 和 `pct_of_total` 值。這些資料欄會識別資料表的大小，以及資料表耗用的原始磁碟空間百分比。原始磁碟空間包括 Amazon Redshift 保留供內部使用的空間，因此會大於名目磁碟容量，它是可供使用者使用的磁碟空間容量。使用此資訊來確保您的可用磁碟空間至少是您最大資料表的 2.5 倍。有此可用空間可讓系統在處理複雜查詢時將中繼結果寫入至磁碟。

```
select trim(pgn.nspname) as schema, 
trim(a.name) as table, id as tableid, 
decode(pgc.reldiststyle,0, 'even',1,det.distkey ,8,'all') as distkey, dist_ratio.ratio::decimal(10,4) as skew, 
det.head_sort as "sortkey", 
det.n_sortkeys as "#sks", b.mbytes,  
decode(b.mbytes,0,0,((b.mbytes/part.total::decimal)*100)::decimal(5,2)) as pct_of_total, 
decode(det.max_enc,0,'n','y') as enc, a.rows, 
decode( det.n_sortkeys, 0, null, a.unsorted_rows ) as unsorted_rows , 
decode( det.n_sortkeys, 0, null, decode( a.rows,0,0, (a.unsorted_rows::decimal(32)/a.rows)*100) )::decimal(5,2) as pct_unsorted 
from (select db_id, id, name, sum(rows) as rows, 
sum(rows)-sum(sorted_rows) as unsorted_rows 
from stv_tbl_perm a 
group by db_id, id, name) as a 
join pg_class as pgc on pgc.oid = a.id
join pg_namespace as pgn on pgn.oid = pgc.relnamespace
left outer join (select tbl, count(*) as mbytes 
from stv_blocklist group by tbl) b on a.id=b.tbl
inner join (select attrelid, 
min(case attisdistkey when 't' then attname else null end) as "distkey",
min(case attsortkeyord when 1 then attname  else null end ) as head_sort , 
max(attsortkeyord) as n_sortkeys, 
max(attencodingtype) as max_enc 
from pg_attribute group by 1) as det 
on det.attrelid = a.id
inner join ( select tbl, max(mbytes)::decimal(32)/min(mbytes) as ratio 
from (select tbl, trim(name) as name, slice, count(*) as mbytes
from svv_diskusage group by tbl, name, slice ) 
group by tbl, name ) as dist_ratio on a.id = dist_ratio.tbl
join ( select sum(capacity) as  total
from stv_partitions where part_begin=0 ) as part on 1=1
where mbytes is not null 
order by  mbytes desc;
```

# 識別具有巢狀迴圈的查詢
<a name="identify-queries-with-nested-loops"></a>

下列查詢可識別已針對巢狀迴路記錄提醒事件的查詢。如需如何修正巢狀迴路條件的資訊，請參閱[巢狀迴圈](query-performance-improvement-opportunities.md#nested-loop)。

```
select query, trim(querytxt) as SQL, starttime 
from stl_query 
where query in (
select distinct query 
from stl_alert_event_log 
where event like 'Nested Loop Join in the query plan%') 
order by starttime desc;
```

# 檢閱查詢的佇列等候時間
<a name="review-queue-wait-times-for-queries"></a>

下列查詢顯示最近的查詢在執行之前等候查詢佇列中開放位置的時間。如果您看見較高的等候時間趨勢，您可能想要修改您的查詢佇列組態以獲得更好的傳輸量。如需詳細資訊，請參閱[實作手動 WLM](cm-c-defining-query-queues.md)。

```
select trim(database) as DB , w.query, 
substring(q.querytxt, 1, 100) as querytxt,  w.queue_start_time, 
w.service_class as class, w.slot_count as slots, 
w.total_queue_time/1000000 as queue_seconds, 
w.total_exec_time/1000000 exec_seconds, (w.total_queue_time+w.total_Exec_time)/1000000 as total_seconds 
from stl_wlm_query w 
left join stl_query q on q.query = w.query and q.userid = w.userid 
where w.queue_start_Time >= dateadd(day, -7, current_Date) 
and w.total_queue_Time > 0  and w.userid >1   
and q.starttime >= dateadd(day, -7, current_Date) 
order by w.total_queue_time desc, w.queue_start_time desc limit 35;
```

# 依資料表檢閱查詢提醒
<a name="review-query-alerts-by-table"></a>

下列查詢可識別已為其記錄提醒事件的資料表，也可識別最常引發的提醒類型。

如果具有已識別資料表資料列的 `minutes` 值較高，請檢查資料表，以查看它是否需要例行維護，例如對它執行 [ANALYZE](r_ANALYZE.md) 或 [VACUUM](r_VACUUM_command.md)。

如果資料列的 `count` 值較高但 `table` 值為 null，請對 STL\$1ALERT\$1EVENT\$1LOG 執行查詢，以取得關聯的 `event` 值，調查為何這麼常引發該提醒。

```
select trim(s.perm_table_name) as table, 
(sum(abs(datediff(seconds, s.starttime, s.endtime)))/60)::numeric(24,0) as minutes, trim(split_part(l.event,':',1)) as event,  trim(l.solution) as solution, 
max(l.query) as sample_query, count(*) 
from stl_alert_event_log as l 
left join stl_scan as s on s.query = l.query and s.slice = l.slice 
and s.segment = l.segment and s.step = l.step
where l.event_time >=  dateadd(day, -7, current_Date) 
group by 1,3,4 
order by 2 desc,6 desc;
```

# 識別具有遺漏統計資訊的資料表
<a name="identify-tables-with-missing-statistics"></a>

下列查詢提供您要對遺漏統計資料的資料表執行的查詢計數。如果此查詢傳回任何資料列，請查看 `plannode` 值來判斷受影響的資料表，然後對其執行[ANALYZE](r_ANALYZE.md)。

```
select substring(trim(plannode),1,100) as plannode, count(*) 
from stl_explain 
where plannode like '%missing statistics%' 
group by plannode 
order by 2 desc;
```

# 查詢故障診斷
<a name="queries-troubleshooting"></a>

此小節提供快速的參考，用於識別和解決使用 Amazon Redshift 查詢時可能遇到的部分最常見和最嚴重的問題。

**Topics**
+ [連線失敗](queries-troubleshooting-connection-fails.md)
+ [查詢懸置](queries-troubleshooting-query-hangs.md)
+ [查詢耗費太長時間](queries-troubleshooting-query-takes-too-long.md)
+ [載入失敗](queries-troubleshooting-load-fails.md)
+ [載入耗費太長時間](queries-troubleshooting-load-takes-too-long.md)
+ [載入資料不正確](queries-troubleshooting-load-data-incorrect.md)
+ [設定 JDBC 擷取大小參數](set-the-JDBC-fetch-size-parameter.md)

這些建議可做為進行故障排除的起點。您也可以參閱下列資源以取得更詳細的資訊。

如需 Amazon Redshift 功能中可能影響應用程式的行為變更相關資訊，請參閱[行為變更](https://docs.aws.amazon.com/redshift/latest/mgmt/behavior-changes.html)。
+ [存取 Amazon Redshift 叢集和資料庫](https://docs.aws.amazon.com/redshift/latest/mgmt/using-rs-tools.html)
+ [自動資料表最佳化](t_Creating_tables.md)
+ [在 Amazon Redshift 中載入資料](t_Loading_data.md)
+ [教學課程：從 Amazon S3 載入資料](tutorial-loading-data.md)

# 連線失敗
<a name="queries-troubleshooting-connection-fails"></a>

您的查詢連線可能由於下列原因而失敗。我們建議以下故障診斷方法。

**用戶端無法連線至伺服器**  
如果您使用 SSL 或伺服器憑證，對連線問題進行故障排除時，請先移除此複雜度。然後在您找到解決方案時，將 SSL 或伺服器憑證新增回去。如需詳細資訊，請參閱《Amazon Redshift 管理指南》**中的[設定連線的安全性選項](https://docs.aws.amazon.com/redshift/latest/mgmt/connecting-ssl-support.html)。

**連線遭拒**  
一般來說，收到錯誤訊息指出無法建立連線時，它表示存取叢集的許可發生問題。如需詳細資訊，請參閱《Amazon Redshift 管理指南》**中的[連線遭拒或失敗](https://docs.aws.amazon.com/redshift/latest/mgmt/connecting-refusal-failure-issues.html)。

# 查詢懸置
<a name="queries-troubleshooting-query-hangs"></a>

您的查詢可以由於下列原因而當掉或停止回應。我們建議以下故障診斷方法。

**對資料庫的連線已丟棄**  
減少最大傳輸單位 (MTU) 的大小。MTU 大小決定可以透過您的網路連線在一個乙太網路訊框中傳輸的封包最大大小 (位元組)。如需詳細資訊，請參閱《Amazon Redshift 管理指南》**中的[已中斷與資料庫的連線](https://docs.aws.amazon.com/redshift/latest/mgmt/connecting-drop-issues.html)。

**對資料庫的連線逾時**  
執行長時間查詢 (例如 COPY 命令) 時，對資料庫的用戶端連線似乎懸置或逾時。在此情況下，您可能會發現 Amazon Redshift 主控台顯示查詢已完成，但用戶端工具本身仍似乎在執行查詢。取決於連線停止的時間，查詢的結果可能遺漏或不完整。當中繼網路元件終止閒置的連線時，會發生此影響。如需詳細資訊，請前往《Amazon Redshift 管理指南》**中的[防火牆逾時問題](https://docs.aws.amazon.com/redshift/latest/mgmt/connecting-firewall-guidance.html)。

**ODBC 發生用戶端記憶體不足錯誤**  
若您的用戶端應用程式使用 ODBC 連線，且您的查詢建立的結果集太大，無法納入記憶體中，則您可以使用資料指標將結果集串流到用戶端應用程式。如需詳細資訊，請參閱[DECLARE](declare.md)及[使用游標時的效能考量](declare.md#declare-performance)。

**JDBC 發生用戶端記憶體不足錯誤**  
嘗試透過 JDBC 連線擷取大型結果集時，您可能會遇到用戶端記憶體不足錯誤。如需詳細資訊，請參閱[設定 JDBC 擷取大小參數](set-the-JDBC-fetch-size-parameter.md)。

**可能有死鎖**  
如果有可能的死鎖，請嘗試下列：
+ 檢視 [STV\$1LOCKS](r_STV_LOCKS.md) 和 [STL\$1TR\$1CONFLICT](r_STL_TR_CONFLICT.md) 系統資料表來尋找牽涉到對超過一個資料表進行更新的衝突。
+ 使用 [PG\$1CANCEL\$1BACKEND](PG_CANCEL_BACKEND.md) 函數來取消一或多個有衝突的查詢。
+ 使用 [PG\$1TERMINATE\$1BACKEND](PG_TERMINATE_BACKEND.md) 函數來終止工作階段，它可強制終止的工作階段中任何目前執行中的交易釋出所有鎖定和復原交易。
+ 排程並行寫入操作時務必謹慎。如需詳細資訊，請參閱[管理並行寫入操作](c_Concurrent_writes.md)。

# 查詢耗費太長時間
<a name="queries-troubleshooting-query-takes-too-long"></a>

您的查詢可能由於下列原因而花費太長的時間。我們建議以下故障診斷方法。

**資料表未進行優化**  
設定資料表的排序索引鍵、配送樣式和壓縮編碼，以善加利用平行處理。如需詳細資訊，請參閱[自動資料表最佳化](t_Creating_tables.md) 

**查詢正在寫入磁碟**  
您的查詢可能會在查詢執行的至少一部分寫入至磁碟。如需詳細資訊，請參閱[查詢效能改善](query-performance-improvement-opportunities.md)。

**查詢必須等候其他查詢完成**  
您可以透過建立查詢佇列和指派不同類型的查詢至適當的佇列，來改善整體系統效能。如需詳細資訊，請參閱[工作負載管理](cm-c-implementing-workload-management.md)。

**查詢未進行優化**  
分析解釋計畫以尋找重新寫入查詢或最佳化資料庫的機會。如需詳細資訊，請參閱[建立和解譯查詢計畫](c-the-query-plan.md)。

**查詢需要更多記憶體來執行**  
如果特定查詢需要更多記憶體，您可以透過增加[wlm\$1query\$1slot\$1count](r_wlm_query_slot_count.md)來增加可用記憶體。

**資料庫要求執行 VACUUM 命令**  
每當您新增、刪除或修改大量資料列時執行 VACUUM 命令，除非您以排序索引鍵順序載入您的資料。VACUUM 命令會重新組織您的資料以保有排序順序和還原效能。如需詳細資訊，請參閱[清空資料表](t_Reclaiming_storage_space202.md)。

## 疑難排解長期執行查詢的其他資源
<a name="queries-troubleshooting-cross-refs"></a>

以下是有助於調整查詢的系統檢視主題和其他文件章節：
+ [STV\$1INFLIGHT](r_STV_INFLIGHT.md) 系統檢視會顯示叢集上執行的查詢。將它與 [STV\$1RECENTS](r_STV_RECENTS.md) 一起使用，以確定當前正在執行或最近完成的查詢會很有幫助。
+ [SYS\$1QUERY\$1HISTORY](SYS_QUERY_HISTORY.md)對於疑難排解很有用。它顯示 DDL 和 DML 查詢以及相關屬性，例如其目前的狀態 (例如 `running` 或 `failed`)、每個查詢執行所花費的時間，以及查詢是否在並行擴展叢集上執行。
+ [STL\$1QUERYTEXT](r_STL_QUERYTEXT.md) 會擷取 SQL 命令的查詢文字。此外，將 STL\$1QUERYTEXT 聯結至 STV\$1INFLIGHT 的 [SVV\$1QUERY\$1INFLIGHT](r_SVV_QUERY_INFLIGHT.md)，會顯示更多查詢中繼資料。
+ 交易鎖定衝突可能是查詢效能問題的可能來源。如需目前在資料表上保留鎖定之交易的相關資訊，請參閱[SVV\$1TRANSACTIONS](r_SVV_TRANSACTIONS.md)。
+ [識別最適合調整的查詢](https://docs.aws.amazon.com/redshift/latest/dg/diagnostic-queries-for-query-tuning.html#identify-queries-that-are-top-candidates-for-tuning)會提供疑難排解查詢，協助您判斷最近執行的查詢最耗時。這可以幫助您將精力集中在需要改進的查詢上。
+ 如果您想要進一步探索查詢管理並瞭解如何管理查詢佇列，[工作負載管理](cm-c-implementing-workload-management.md)顯示如何執行此操作。工作負載管理是一項進階功能，我們建議您在大多數情況下自動化工作負載

# 載入失敗
<a name="queries-troubleshooting-load-fails"></a>

您的資料載入可能由於下列原因而失敗。我們建議以下故障診斷方法。

**資料來源位於不同的 AWS 區域**  
根據預設，COPY 命令中指定的 Amazon S3 儲存貯體或 Amazon DynamoDB 資料表必須與叢集位於相同的 AWS 區域。如果您的資料和您的叢集位於不同的區域，您會收到類似以下的錯誤：

```
The bucket you are attempting to access must be addressed using the specified endpoint.
```

如果有可能，請確定您的叢集和您的資料來源位於相同區域。您可以使用 [REGION](copy-parameters-data-source-s3.md#copy-region) 選項搭配 COPY 命令來指定不同的區域。

**注意**  
如果您的叢集和資料來源位於不同的 AWS 區域，則會產生資料傳輸成本。您的延遲也會更高。

**COPY 命令失敗**  
查詢 STL\$1LOAD\$1ERRORS 以探索特定載入期間發生的錯誤。如需詳細資訊，請參閱[STL\$1LOAD\$1ERRORS](r_STL_LOAD_ERRORS.md)。

# 載入耗費太長時間
<a name="queries-troubleshooting-load-takes-too-long"></a>

您的載入操作可能由於下列原因而花費太長的時間。我們建議以下故障診斷方法。

**從單一檔案 COPY 載入資料**  
將您的載入資料分割至多個檔案。當您從多個檔案載入所有資料時，Amazon Redshift 將被迫執行序列化載入，其速度非常慢。檔案的數量應該是您的叢集中配量數量的倍數，而檔案應該是大約相等的大小，壓縮後介於 1 MB 與 1 GB 之間。如需詳細資訊，請參閱[設計查詢的 Amazon Redshift 最佳實務](c_designing-queries-best-practices.md)。

**載入操作使用多個 COPY 命令**  
如果您同時使用多個 COPY 命令從多個檔案載入一個資料表，Amazon Redshift 將被迫執行序列化載入，其速度非常慢。在此情況下，請使用單一 COPY 命令。

# 載入資料不正確
<a name="queries-troubleshooting-load-data-incorrect"></a>

您的 COPY 操作可能透過下列方式載入不正確的資料。我們建議以下故障診斷方法。

**載入錯誤的檔案**  
使用物件字首來指定資料檔案可能導致讀取不需要的檔案。相反地，請使用資訊清單檔案來指定要載入的確切檔案。如需詳細資訊，請參閱 COPY 命令的 [copy_from_s3_manifest_file](copy-parameters-data-source-s3.md#copy-manifest-file) 選項和 COPY 範例中的 [Example: COPY from Amazon S3 using a manifest](r_COPY_command_examples.md#copy-command-examples-manifest)。

# 設定 JDBC 擷取大小參數
<a name="set-the-JDBC-fetch-size-parameter"></a>

根據預設，Redshift JDBC 驅動程式會使用環形緩衝區來有效管理記憶體，並防止out-of-memory錯誤。擷取大小參數僅適用於明確停用環緩衝區的情況。如需詳細資訊，請檢閱[連結](https://docs.aws.amazon.com/redshift/latest/mgmt/jdbc20-configuration-options.html#jdbc20-enablefetchringbuffer-option)。在此組態中，您應該設定擷取大小，以控制每個批次中要擷取的資料列數量。

在下列情況下使用擷取大小參數：
+ 您需要精細控制以資料列為基礎的批次
+ 使用需要傳統擷取大小行為的舊版應用程式

當環緩衝區停用時，JDBC 驅動程式預設會一次收集查詢的所有結果。傳回大型結果集的查詢可能會耗用過多記憶體。若要以批次而非一次全部擷取結果集，請在應用程式中設定 JDBC 擷取大小參數。

**注意**  
ODBC 不支援擷取大小。

為求最佳效能，請將擷取大小設定為不會導致記憶體不足錯誤的最高值。較低的擷取大小值會造成更多伺服器來回行程，進而延長執行時間。伺服器會預留資源，包括 WLM 查詢位置和關聯的記憶體，直到用戶端擷取整個結果集或查詢取消為止。適當地調校擷取大小時，那些資源會更快速釋出，使得它們可供其他查詢使用。

**注意**  
如果您必須擷取大型資料集，建議使用 [UNLOAD](https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD.html) 陳述式來將資料傳輸至 Amazon S3。使用 UNLOAD 時，運算節點會平行運作，以加速資料的傳輸。

如需設定 JDBC 擷取大小參數的相關資訊，請前往 PostgreSQL 文件中的[根據游標取得結果](https://jdbc.postgresql.org/documentation/query/#getting-results-based-on-a-cursor)。