

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

# 查詢規劃器 v3
<a name="query-planner-v3"></a>

Amazon DocumentDB 8.0 中的規劃器第 3 版支援 21 個彙總階段，包括 6 個新階段。規劃器 V3 隨附對不同命令的內建支援。與 Amazon DocumentDB 5.0 中的規劃器 v2 相比，它可提供高達 2 倍的整體效能改善。Amazon DocumentDB 8.0 中的所有新功能和運算子都與規劃器 v3 相容。Amazon DocumentDB 8.0 中由規劃工具 v3 支援的新彙總階段包括 \$1replaceWith、\$1vectorSearch、\$1merge、\$1set、\$1unset、\$1bucket。規劃器 v3 也支援 Amazon DocumentDB 8.0 的新功能和運算子，包括定序、檢視、\$1merge、\$1pow、\$1rand、\$1dateTrunc、\$1dateToParts、\$1dateFromParts。

**Topics**
+ [先決條件](#nqp-prerequisites)
+ [選取規劃器 3.0 版做為預設查詢規劃器](#second-concept-chapter)
+ [最佳實務](#nqp-best-practices)
+ [限制](#nqp-limitations)
+ [`aggregate` 和 `distinct`運算子的改進](#operator-improvements)
+ [規劃器版本 1.0、3.0 和 MongoDB 之間的潛在行為差異](#planner-behavior-differences)

## 先決條件
<a name="nqp-prerequisites"></a>

下列先決條件適用於規劃器 3.0 版：
+ 規劃器 3.0 版可在引擎 8.0 版提供的所有區域使用。
+ 選取引擎 8.0 版時，規劃器 3.0 版是預設查詢規劃器。

## 選取規劃器 3.0 版做為預設查詢規劃器
<a name="second-concept-chapter"></a>

如果您在 Amazon DocumentDB 8.0 中變更預設查詢規劃器，且需要還原至規劃器 v3，您可以從主控台或 CLI 執行此操作：
+ 請依照中的步驟[修改 Amazon DocumentDB 叢集參數](cluster_parameter_groups-parameters.md)修改叢集的參數群組。
+ 對於名為「plannerVersion」的參數，將值變更為 3.0，表示規劃器 3.0 版。
+ 選取**立即套用** （選取在**重新開機時套用**會使選取無效，直到叢集下次重新開機為止）。

## 最佳實務
<a name="nqp-best-practices"></a>

如需預期結果，請在套用規劃器 3.0 版時使用下列最佳實務：
+ 在全域叢集中，在兩個區域的叢集參數群組中選取相同的`plannerVersion`值 (1.0 或 2.0 或 3.0)。請注意，在主要和次要區域中選取不同的規劃器版本可能會導致查詢行為和效能不一致。
+ 在排定的維護時段或減少的流量期間更新到規劃器 3.0 版將最不會造成干擾，因為如果在工作負載主動執行時變更規劃器版本，可能會提高錯誤率。

## 限制
<a name="nqp-limitations"></a>

下列限制適用於規劃器 3.0 版：
+ 彈性叢集不支援規劃器 3.0 版，這會回到規劃器 1.0 版。
+ 雖然規劃器 v1 允許使用 'planHint' 來確保查詢最佳化工具已選取特定查詢計畫，但規劃器 v3 不允許使用 'planHint'，並依賴內部最佳化來選擇指定查詢的最佳計畫。

## `aggregate` 和 `distinct`運算子的改進
<a name="operator-improvements"></a>

規劃器 3.0 版推出跨 \$1aggregate 階段和 \$1distinct 命令的改進。以下是一些最值得注意的改進。
+ 規劃器會盡可能提早在管道中移動 \$1match 階段，減少後續階段處理的文件數量。

  ```
  //Planner v1
  db.orders.aggregate([
    { $project: { customerId: 1, orderDate: 1, totalAmount: 1 } },
    { $match: { customerId: { $gt: 1000 } } }
  ])
  
  // Planner v3 pulls up the match since customerId exists in original documents
  // Optimized internally as:
  db.orders.aggregate([
    { $match: { customerId: { $gt: 1000 } } },  // Pulled up before project
    { $project: { customerId: 1, orderDate: 1, totalAmount: 1 } }
  ])
  ```
+ 規劃器在相同欄位操作時，會自動結合 \$1lookup 和 \$1unwind 階段，減少中繼資料處理並改善效能。

  ```
                   Example query:
  //Planner v1
  db.orders.aggregate([
    { $lookup: { from: "products", localField: "productId", foreignField: "_id", as: "productInfo" } },
    { $unwind: "$productInfo" },
    { $project: { orderDate: 1, "productInfo.name": 1, "productInfo.price": 1 } }
  ])
  
  // Planner version 3.0 optimizes this internally by coalescing the $lookup and $unwind stages
  ```
+ 規劃器 3.0 版推出新的 Distinct Scan 執行策略，可大幅改善低基數索引上不同操作的效能。

  ```
                   Example query:
  //// If there is a low cardinality index on "category", you may see a query plan like below
  db.explain().products.distinct("category")
  
  "queryPlanner" : {
          "plannerVersion" : 3,
          "namespace" : "db.products",
          "winningPlan" : {
                  "stage" : "AGGREGATE",
                  "inputStage" : {
                          "stage" : "DISTINCT_SCAN",
                          "inputStage" : {
                                  "stage" : "IXONLYSCAN",
                                  "indexName" : "category_1",
                                  "direction" : "forward"
                          }
                  }
          }
  }
  ```

## 規劃器版本 1.0、3.0 和 MongoDB 之間的潛在行為差異
<a name="planner-behavior-differences"></a>

在某些情況下，規劃器 3.0 版可能會產生與規劃器 1.0 版略有不同的結果。本節會逐步解說這些可能性的一些範例。

------
#### [ Feature Differences ]
+ 在空集合上或配對等先前階段篩選所有文件時，規劃器 v1 會提供輸出「欄位」：0。規劃器 v3 和 MongoDB 不會提供任何輸出。
+ 使用 Plannerv1，如果上一個階段傳回的文件少於 n 個，則 \$1"\$1skip"：n\$1 不會略過。無論傳回的文件數量為何，Plannerv3 和 MongoDB 都會正確略過。
+  當 \$1lookup 中參考的外部集合不存在時，Plannerv1 會擲回錯誤。規劃器 v3 和 MongoDB 會將外部集合視為空白集合，並執行 \$1lookup。

  ```
  db.coll.aggregate([
      {$lookup: {from: "does_not_exist", localField: "a", foreignField: "a", as: "c"}}
  ])
  ```
+  只有規劃器 v1 將允許在管道規劃器 v2/v3 中使用多個 \$1search 會擲回錯誤，且 MongoDB 不支援該錯誤。

  ```
  VectorSearch = { "$search": { "vectorSearch": {
     "vector": [0.2, 0.5, 0.8], 
     "path": "vectorEmbedding", 
     "similarity": "cosine", 
     "k": 2, 
     "efSearch": 1  
     }}}
  db.coll.aggregate([VectorSearch, VectorSearch])
  ```
+  只有規劃器 v3 可在 vectorSearch 階段不是第一個階段時運作。在此情況下，MongoDB 會擲回錯誤，而規劃器 v1 不支援 \$1vectorSearch 階段。

  ```
  VectorSearch = { {"$vectorSearch": { 
      "queryVector": [0.2, 0.5, 0.8], 
      "path": "vectorEmbedding", 
      "similarity": "euclidean", 
      "limit": 4, 
      "numCandidates": 100} }
      
  db.coll.aggregate([$match:{}, VectorSearch])
  ```

------