2012-07-28 86 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