2012-07-28 126 views
4

我有一個與MongoDB交互的PHP應用程序。直到最近,該應用程序工作正常,但幾天前我發現該應用程序開始反應非常慢。其中一個藏品已經拍攝了50萬多條記錄。所以MongCursor對該集合的任何查詢都會超時。MongoDB記錄太多?

我不認爲500K記錄太多了。其他使用mongodb的頁面也開始減慢,但沒有使用帶有500k記錄的集合的頁面減少。不與MongoDB交互的靜態頁面仍然很快響應。

我不知道這裏可能是什麼問題。我已將索引編入索引,所以這似乎不成問題。另一點要注意的是,服務器上的RAM規格是512 MB,當PHP執行Mongo時,最高命令顯示15000k內存空閒。

任何幫助將不勝感激。

+0

有用以包括與[.explain()](HTTP一個示例查詢://www.mongodb.org/display/DOCS/Explain)。 – Stennie 2012-07-28 15:10:34

回答

7

要從聊天室總結隨訪,這個問題實際上涉及到這是做所有〜500K的文件的掃描一個發現()查詢找到15:

db.tweet_data.find({ 
    $or: 
    [ 
     { in_reply_to_screen_name: /^kunalnayyar$/i, handle: /^kaleycuoco$/i, id: { $gt: 0 } }, 
     { in_reply_to_screen_name: /^kaleycuoco$/i, handle: /^kunalnayyar$/i, id: { $gt: 0 } } 
    ], 
    in_reply_to_status_id_str: { $ne: null } 
}).explain() 
{ 
    "cursor" : "BtreeCursor id_1", 
    "nscanned" : 523248, 
    "nscannedObjects" : 523248, 
    "n" : 15, 
    "millis" : 23682, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "isMultiKey" : false, 
    "indexOnly" : false, 
    "indexBounds" : { 
     "id" : [ 
      [ 
       0, 
       1.7976931348623157e+308 
      ] 
     ] 
    } 
} 

此查詢使用case-insensitive regular expressions這將不會有效地使用索引(儘管在這種情況下實際上沒有定義一個索引)。

建議的方法:

  • 創建用於搜索目的小寫handle_lcinreply_lc字段

  • 在那些添加compound index

    db.tweet.ensureIndex({handle_lc:1, inreply_lc:1})

  • 化合物索引的順序允許有效查找的所有鳴叫或者通過handle或通過精確匹配代替正則表達式(handle,in_reply_to

  • 搜索:

db.tweet_data.find({ $or: [ { in_reply_to_screen_name:'kunalnayyar', handle:'kaleycuoco', id: { $gt: 0 } }, { in_reply_to_screen_name:'kaleycuoco', handle:'kunalnayyar', id: { $gt: 0 } } ], })

+0

爲什麼我不能在這裏使用單個索引?另外,我意識到另一個問題 - 在字段「id」上有降序排列。所以我想我將不得不修改我的索引,有什麼建議? – 2012-07-28 19:29:37

+0

@AyushChaudhary:在一般情況下,MongoDB只使用[每個查詢一個索引](http://www.mongodb.org/display/DOCS/Indexing+Advice+and+FAQ#IndexingAdviceandFAQ-Oneindexperquery。)。如果你期望有很多推文並且通過handle + replyto進行搜索,那麼複合索引就會有意義,因此[index匹配你的查詢](http://www.mongodb.org/display/DOCS/Indexing+Advice+and + FAQ#IndexingAdviceandFAQ-Oneindexperquery)。如果你總是用_id排序,你也可以將它添加到複合索引中。 – Stennie 2012-07-28 20:55:03

+0

閱讀MongoDB wiki上的[索引策略](http://www.mongodb.org/display/DOCS/Indexing+Advice+and+FAQ)頁面以獲取更多提示。如果使用[explain()](http://www.mongodb.org/display/DOCS/Explain)比較不同方法的輸出結果,您應該更好地瞭解如何優化查詢/索引。您可能希望使用[limit()](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Blimit%28%29%7D%7D)以及[sort( )](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bsort%28%29%7D%7D)以避免獲取太多文檔。 – Stennie 2012-07-28 21:01:17

0

是的,500K +應該沒關係。據我所知,集合中文檔的數量沒有真正的「限制」。可能它是MongoDB可以生成的_id字段的唯一組合的數量。但這將大於500K ..在你的情況下,我懷疑是,也許你的查詢不是很有選擇性。所以當收集文件較少時,你沒有注意到這個問題。但隨着增加,它似乎越來越遲鈍......就像MongoCursor返回了多少文檔?

+0

它實際上有所不同。在某些情況下,它可以給我100個,大約爲0,大約500個。 – 2012-07-28 13:07:36

+0

那麼你是否已經檢查過返回的文檔數量有多不同? – 2012-07-28 13:10:15

+0

記錄數量變化不大。光標在大多數情況下保持超時30秒 – 2012-07-28 13:12:30