如要排解查詢速度緩慢的問題,請使用查詢說明取得查詢執行計畫和執行階段執行設定檔。視執行設定檔而定,您可以採取下列步驟,盡可能提高查詢效能:
限制結果數量
使用執行樹狀結構中的「傳回的記錄」欄位,判斷查詢是否傳回多份文件。建議您使用 $limit 子句,限制傳回的文件數量。這樣一來,結果透過網路傳回用戶端時,序列化位元組大小就會減少。如果 Limit 節點前面有 MajorSort 節點,查詢引擎可以合併 Limit 和 MajorSort 節點,並將完整的記憶體內具體化和排序作業替換為 TopN 排序,減少查詢所需的記憶體。
限制結果文件大小
建議使用 $project 子句限制傳回的文件大小,避免擷取不必要的欄位。這有助於降低處理中繼結果的運算和記憶體成本,以及透過網路將結果傳回用戶端時的序列化位元組大小。如果查詢中參照的所有欄位都由一般索引 (非多鍵) 涵蓋,則查詢也會完全由索引掃描涵蓋,因此不需要從主要儲存空間擷取文件。
使用索引
請按照下列操作說明設定及最佳化索引。
判斷查詢是否使用索引
您可以查看執行樹狀結構中的葉節點,判斷查詢是否使用索引。如果執行樹狀結構的葉節點是 TableScan 節點,表示查詢未使用索引,而是從主要儲存空間掃描文件。如果正在使用索引,執行樹狀結構的葉節點會顯示索引 ID 和索引欄位。
判斷使用的索引是否可以最佳化
如果索引能減少查詢引擎需要從主要儲存空間擷取的文件數量,或其欄位排序能滿足查詢的排序需求,則該索引對查詢很有幫助。
如果查詢使用索引,但查詢引擎仍擷取並捨棄許多文件 (由傳回許多記錄的掃描節點,以及傳回少量記錄的篩選器節點識別),這表示使用索引滿足的查詢述詞不具選擇性。如要建立更合適的索引,請參閱「建立索引」。
如果查詢使用非多鍵索引,但查詢引擎仍對結果集執行記憶體內重新排序 (由查詢執行樹狀結構中的 MajorSort 節點識別),這表示所用索引無法用於提供查詢的排序需求。如要建立更合適的索引,請參閱下一節。
正在最佳化 $lookup 項查詢
您可以將索引新增至 from 集合,藉此最佳化 $lookup 查詢,讓作業有效率地找出相符文件,而不必掃描整個集合。
$lookup (localField和foreignField)
如果您在 $lookup 階段使用 localField 和 foreignField 選項,請在 from 集合中的 foreignField 上建立索引。
含有巢狀管道的$lookup
如果您在 $lookup 階段使用 pipeline 選項,並搭配 $match 階段,請在外部集合中涉及的欄位上建立索引,避免掃描整個集合:
- 對於具有篩選語意的
$match階段 (例如{$match: {a: true}}),請在外部集合 (a) 中涉及的欄位上建立索引。 - 如果
$match階段的匯總語意會將欄位與常數值 (例如{$match: {$expr: {$gt: [a, 10]}}}) 進行比較,或在欄位與let中定義的變數之間進行相等比較 (eq或in) (例如{$match: {$expr: {$eq: [a, "$$a"]}}}),請為外部集合中的相關欄位建立索引。請注意,規劃時不會使用多鍵索引。
建立索引
按照索引管理說明文件建立索引。為確保查詢可以使用索引,請建立一般 (非多鍵) 索引,並依下列順序排列欄位:
- 所有會用於等號運算子的欄位。如要盡可能提高跨查詢重複使用的機率,請按照查詢中等號運算子中欄位出現次數的遞減順序排列欄位。
- 所有要排序的欄位 (順序相同)。
- 將用於範圍或不等式運算子的欄位,依查詢限制選擇性遞減排序。
- 在索引中,將做為查詢一部分傳回的欄位:在索引中加入這類欄位,可讓索引涵蓋查詢,並避免從主要儲存空間擷取文件。
如果查詢涉及篩選及排序陣列欄位,建議建立多鍵索引。
使用查詢提示
如果您已為查詢建立更合適的索引,但查詢引擎並未使用該索引,則可以使用查詢提示覆寫查詢引擎的索引偏好設定。
如要進一步瞭解使用查詢說明功能執行的查詢輸出內容,請參閱「查詢執行參考資料」。