4

我有一个与 MongoDB 交互的 PHP 应用程序。直到最近,该应用程序运行良好,但几天前我发现该应用程序开始响应非常缓慢。其中一个系列的记录已高达 500K+。因此,对该集合的任何查询的 MongCursor 都会超时。

我不认为 500K 记录太多了。其他使用 mongodb 的页面也开始变慢,但不如使用 500k 记录的集合的页面慢。不与 MongoDB 交互的静态页面仍然可以快速响应。

我不确定这里可能是什么问题。我已经索引了这些集合,所以这似乎不是问题。还有一点需要注意的是,服务器上的 RAM 规格是 512 MB,当 PHP 执行 Mongo 时,top 命令显示 15000k 内存可用。

任何帮助将不胜感激。

4

2 回答 2

7

总结聊天室的后续情况,这个问题实际上与 find() 查询有关,该查询正在扫描所有约 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 
            ] 
        ] 
    } 
}

This query is using case-insensitive regular expressions which won't make efficient use of an index (though there wasn't actually one defined, in this case).

Suggested approach:

  • create lowercase handle_lc and inreply_lc fields for search purposes

  • add a compound index on those:

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

  • the order of the compound index allows efficient find of all tweets either by handle or by (handle,in_reply_to)

  • search by exact match instead of regex:

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 } } ], })

于 2012-07-28T15:09:26.787 回答
0

是的,500K+ 应该没问题..据我所知,集合中的文档数量没有真正的“限制”..可能是 _id 字段 MongoDB 可以生成的唯一组合的数量..但这会很多大于 500K ..在您的情况下,我怀疑是,您的查询可能不是很有选择性。因此,当集合中的文档较少时,您不会注意到该问题。但是随着增加,它似乎突然变得迟缓了..比如,MongoCursor 返回了多少文件?

于 2012-07-28T12:58:43.553 回答