2014-02-27 52 views
0

這是mongodb中的一個簡單搜索的解釋,它花費超過2.4秒和更多來檢索數據。如果我添加索引(搜索參數),它需要超過5秒。如何提高mongo簡單搜索查詢的性能

查詢

db.CX_EMPLOYEES.find({ "$or" : [{ "AML_FULLNAME" : /RAJ/ }, 
{ "AML_FULLALIAS" : /RAJ/ }] }) 

解釋

{ 
     "cursor" : "BasicCursor", 
     "isMultiKey" : false, 
     "n" : 79, 
     "nscannedObjects" : 504570, 
     "nscanned" : 504570, 
     "nscannedObjectsAllPlans" : 504570, 
     "nscannedAllPlans" : 504570, 
     "scanAndOrder" : false, 
     "indexOnly" : false, 
     "nYields" : 0, 
     "nChunkSkips" : 0, 
     "millis" : 2423, 
     "indexBounds" : {}, 
     "server" : "SERVER:27017" 
    } 

回答

0

沒有任何理由,因爲你使用正則表達式對這個搜索PARAMS添加索引。只有當regExp在開始時有一個錨點時,索引才能改善使用regExp的查找。

db.CX_EMPLOYEES.find({ "$or" : [{ "AML_FULLNAME" : /^RAJ/ }, { "AML_FULLALIAS" : /^RAJ/ }] }) 

documentation

$正則表達式只能有效地使用索引時正則表達式有一個字符串的輸入開始的錨(即^),並且是區分大小寫的匹配。此外,雖然/^a /,/^a.*/和/^a.*$/匹配等效字符串,但它們具有不同的性能特徵。如果存在適當的索引,所有這些表達式都使用索引;不過,/^a.*/和/^a.*$/較慢。/^ a /可以在匹配前綴後停止掃描。

0

沒有很多事情可以做。你有五十萬個元素,你正在全部掃描它們。毫不奇怪,這需要時間。此外,你的搜索是基於正則表達式,它可以在字符串中的任何地方。所以在這種情況下索引不能幫助你。

如果您的搜索是基於單詞,您可以嘗試從字符串中創建數組。例如字符串'Salvador Domingo Dali'將被轉換爲['Salvador', 'Domingo', 'Dali']。如果您要在此陣列上添加索引並嘗試尋找'Dali',那麼搜索將利用此索引。

P.S.數據庫和索引不是一個銀彈。有時你需要一個更好的邏輯來處理大量的數據。

+0

我首先使用數組來存儲名稱,就像您所說的那樣,併爲該數組添加索引,但發現它非常昂貴。這個搜索花費了3-10分鐘,所以我將它改爲單列,這可以減少時間,但這仍然只是我的測試數據。生產將有更多的數據..請幫助一些解決方案 – deepu

+0

你能從數組解決方案和你的文檔中的相關示例中顯示你的解釋嗎? –

1

預定爲2.6版本的MongoDb是full text search功能。如果啓用,它可作爲當前版本的開發預覽版提供。

鑑於查詢的性質,它可能是唯一可能僅使用MongoDb有效的選項。當您嘗試根據您提供的正則表達式執行「字符串包含」搜索時,考慮到您的集合的大小,執行搜索以匹配多個字段上的字符串的性能將會很糟糕。雖然這是一個簡單的概念查詢,但轉換爲高效查詢非常困難。 Mongo需要掃描每個文檔以進行匹配。打破單詞分開並沒有幫助,因爲Mongo仍然需要每文件掃描

如果您可以錨定正則表達式,這意味着它將更改爲「字符串開頭」而不是「字符串包含」,如果您規範化字符串以便忽略所有字符大小寫,並且實現那場比賽將仍然是確切的。例如,a不是á,需要特別處理。

對於這種類型的查詢,Mongo對於生產使用的支持確實有限。您可能會發現全文搜索功能也不適合。如果這個查詢很重要,我會建議考慮其他搜索機制。例如,可能看着像Elastic Search這樣的東西。

+0

在mongodb中使用全文搜索功能是一種可靠的方法或解決方案..?我發現不建議在生產中使用它。 – deepu

+0

2.6現在正在發佈候選版本。我建議你可能想考慮非Mongo解決方案。 – WiredPrairie