有一些問題與您的查詢和索引:
1 $或使用索引不同
MongoDB中只使用一個索引的查詢,處理涉及$or
子句的查詢的除外。來自Indexing Strategies頁面:
通常,MongoDB只使用一個索引來完成大多數查詢。然而,$或查詢的每個子句可以使用不同的指標
同樣來自$or Clauses and Indexes頁:
也就是說,MongoDB的使用索引來評估一個$或表達式,所有條款在$或表達式中必須由索引支持。
關於您的查詢,你可以嘗試重新安排查詢,使$or
條款頂級子句:
{$or: [
{"palabra": {...}, "_p_pais": {...} },
{"palabra": {...}, "languageCodeTatoeba": {...}}
]}
在這種形式下,MongoDB的可以用兩個指標:
- 化合物指數爲
palabra
和_p_pais
條款和
- 化合物指數爲
palabra
和languageCodeTatoeba
條款
請使用explain("executionStats")
檢查索引是否正確使用。您希望最小化的關鍵指標是文檔數量(nReturned
)與檢查的總文檔/關鍵字數量。比率越接近1,查詢的選擇性越高,性能越好。例如,如果MongoDB必須檢查1000個文檔(totalDocsExamined: 1000
),但只返回10個文檔(nReturned: 10
),那麼您的查詢不是很有選擇性(即比例爲10/1000)。理想查詢的比例接近或等於1,例如nReturned: 10, totalDocsExamined: 10
,比例1(10/10)。
有關explain()
的更多信息,請訪問:
2.索引過多
有太多的指標可能會導致:
- 查詢規劃器選擇次優索引,因爲它們都不知道要使用哪個索引,因爲它們看起來都一樣。
- 相對較慢的插入/更新性能,因爲每次插入/更新索引中包含的字段也需要插入/更新索引。
從您發佈的解釋結果,你必須至少這些集合中的指標:
_p_pais_-1__p_user_-1__created_at_-1
languageCodeTatoeba_1_lowercase_1
languageCodeTatoeba_1
languageCodeTatoeba_-1
_p_pais_-1
_p_pais_1_languageCodeTatoeba_1
palabra_-1
palabra_1__created_at_-1
有兩個問題與這組指標:
- 在這些指標,有些是多餘的。例如,
languageCodeTatoeba_1
(上升指數)和languageCodeTatoeba_-1
(下降指數)實際上是相同的指數。其中一個可以被刪除而不會對查詢性能產生任何影響。
- 很多索引是另一個的前綴。例如,
palabra_-1
和palabra_1__created_at_
。 palabra_-1
索引可以被刪除,因爲它是palabra_1__created_at_
索引的前綴。請參閱Compound Index: Prefix頁面瞭解更多詳情。
從粗略地看一眼,你可以到你的索引列表修剪到只包含這4個指標,而不是8:
_p_pais_-1__p_user_-1__created_at_-1
languageCodeTatoeba_1_lowercase_1
_p_pais_1_languageCodeTatoeba_1
palabra_1__created_at_-1
請參閱有關更多信息的索引以下鏈接:
3.爲什麼從長期$or
取出一個條款加快了查詢
這是因爲查詢
{"palabra": {...}, $or: [{"_p_pais": {...}}]}
是基本相同
{"palabra": {...}, "_p_pais": {...}}
假設你有一個複合索引如palabra_1__p_pais_1
,MongoDB將能夠使用該索引。
同樣,
{"palabra": {...}, $or: [{"languageCodeTatoeba": {...}}]}
是基本相同
{"palabra": {...}, "languageCodeTatoeba": {...}}
這種查詢可以使用_p_pais_1_languageCodeTatoeba_1
指數,你已經有你的收藏。
總之,這兩個查詢都很快,因爲您刪除了$or
子句,使MongoDB能夠使用正確的索引。
您可以發佈快速查詢的(。或兩者)的'.explain()'嗎? – Lucas