盡可能提高查詢效能
如要排解查詢速度緩慢的問題,請使用「查詢說明」取得查詢執行計畫和執行階段執行設定檔。以下各節說明如何根據執行設定檔,採取適當步驟來提升查詢效能:
限制結果數量
使用執行樹狀結構中的「傳回的記錄」欄位,判斷查詢是否傳回大量文件。建議使用 limit(...) 階段,限制傳回的文件數量。這樣一來,透過網路傳回用戶端時,結果的序列化位元組大小就會減少。如果 Limit 節點前面有 MajorSort 節點,查詢引擎可以合併 Limit 和 MajorSort 節點,並以 TopN 排序取代完整的記憶體內具體化和排序,進而減少查詢的記憶體需求。
限制結果文件大小
建議使用 select(...) 只傳回必要欄位,或使用 remove_fields(...) 捨棄過大的欄位,藉此限制傳回的文件大小。這有助於減少處理中繼結果的運算和記憶體成本,以及透過網路傳回用戶端時,結果的序列化位元組大小。如果查詢中參照的所有欄位都涵蓋在一般索引中,查詢也可以完全涵蓋在索引掃描中,避免從主要儲存空間擷取文件。
使用索引
請按照下列操作說明設定及最佳化索引。
判斷查詢是否使用索引
如要判斷查詢是否使用索引,請檢查執行樹狀結構中的葉節點。如果執行樹狀結構的葉節點是TableScan 節點,表示查詢未使用索引,而是掃描主要儲存空間中的文件。如果使用索引,執行樹狀結構的葉節點會顯示索引的索引 ID 和索引欄位。
找出更合適的索引
如果索引可減少查詢引擎需要從主要儲存空間擷取的檔案數量,或其欄位排序可滿足查詢的排序需求,則索引對查詢很有用。
如果查詢使用索引,但查詢引擎仍會擷取並捨棄大量文件 (如 Scan 節點傳回大量記錄,接著 Filter 節點傳回少量記錄),這表示使用索引滿足的查詢述詞不具選擇性。如要建立更合適的索引,請參閱「建立索引」。
如果查詢使用索引,但查詢引擎仍在記憶體中重新排序結果集 (如查詢執行樹狀結構中的 MajorSort 節點所示),表示所用索引無法滿足查詢的排序需求。如要建立更合適的索引,請參閱下一節。
建立索引
請參閱索引管理說明文件,瞭解如何建立索引。為確保查詢可以使用索引,請依下列順序建立一般 (而非 Multikey) 索引和欄位:
- 所有將用於等號運算子的欄位。 如要盡量在查詢中重複使用欄位,請依據查詢中等號運算子內欄位的出現次數,以遞減順序排序欄位。
- 所有要排序的欄位 (順序相同)。
- 將用於範圍或不相等運算子的欄位,依查詢限制選擇性遞減排序。
- 將做為索引查詢一部分傳回的欄位:在索引中加入這類欄位,可讓索引涵蓋查詢內容,避免必須從主要儲存空間擷取文件。
強制執行索引或資料表掃描
查詢 Firestore 原生模式時,系統會自動使用可能有助提高查詢效率的任何索引。因此,您不需要為查詢指定索引。不過,如果查詢對工作負載至關重要,建議您使用 forceIndex 選項,以獲得更穩定的效能。
在少數情況下,原生模式的 Firestore 可能會選擇造成查詢延遲增加的索引。如果您按照效能迴歸問題適用的疑難排解步驟操作,並確認嘗試使用不同索引來執行查詢是合理的做法,可以使用 forceIndex 選項指定索引。
您可以在管道作業的任何輸入階段使用 forceIndex 選項,覆寫 Native Mode 中 Firestore 的預設查詢計畫,並指定要使用的索引,或強制執行資料表掃描。
強制使用特定索引
如要強制查詢使用特定索引,請將索引 ID 以字串形式提供給 forceIndex 選項。您可以從控制台或錯誤訊息中找到索引 ID。
以下範例會強制規劃工具使用 ID 為 CICAgOi36pgK 的索引:
// Force Planner to use Index ID CICAgOi36pgK
db.pipeline()
.collectionGroup({ collectionId: "customers", forceIndex: "CICAgOi36pgK" })
.limit(100)
以下列舉幾項強制使用特定索引的用途:
- 測試不同索引的成效。
- 確保查詢使用特定已知最佳索引。
- 如果最佳化工具的預設選擇不適合特定查詢,您可以覆寫最佳化工具。
如果找不到指定的索引,查詢就會失敗。
強制掃描資料表
資料表掃描會讀取集合或產品素材資源集合群組中的文件,但不會使用任何次要索引。如要強制執行資料表掃描,請將 forceIndex 設為 primary。
以下範例會強制執行資料表掃描:
// Force Planner to only do a Full-Table Scan
db.pipeline()
.collectionGroup({ collectionId: "customers", forceIndex: "primary" })
.limit(100)
在下列情況下,您可能會使用資料表掃描:
- 適用於索引負擔不合理的極小集合。
- 查詢會存取集合中的大部分文件。
- 用於偵錯和比較效能。
搭配「查詢說明」使用 forceIndex
您可以使用「查詢說明」,特別是搭配 analyze 選項,觀察 forceIndex 的效果:
- 檢查執行樹狀結構的葉節點,確認 Firestore (原生模式) 在
forceIndex中使用指定的索引 ID。 - 確認使用
forceIndex: "primary"時,計畫中會顯示TableScan節點。 - 比較啟用和未啟用
forceIndex時的延遲時間、掃描的文件數和掃描的索引項目數等成效指標,進一步調整查詢效能。
forceIndex最佳做法
雖然 forceIndex 可提供更多查詢執行控制權,但對於大多數用途而言,原生模式的 Firestore 查詢最佳化工具通常效率很高。使用 forceIndex 時,請考慮下列最佳做法:
- 請謹慎使用
forceIndex。如果您發現預設查詢計畫的效能不彰,請先使用「查詢說明」診斷問題,再強制使用索引。 - 使用
forceIndex時,請務必以實際資料量測試查詢,瞭解查詢的效能和費用特性。 - 請勿在正式環境中對大型集合使用
forceIndex: "primary"。