php - MongoDB 记录太多?

标签 php mongodb

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

我认为 50 万条记录并不过分。使用 mongodb 的其他页面也开始变慢,但没有使用包含 500k 记录的集合的页面慢。不与 MongoDB 交互的静态页面仍然可以快速响应。

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

任何帮助将不胜感激。

最佳答案

总结一下聊天室的跟进,这个问题实际上与 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 
            ] 
        ] 
    } 
}

此查询正在使用 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({ $或: [ { in_reply_to_screen_name:'kunalnayyar', handle:'kaleycuoco', id: { $gt: 0 } }, { in_reply_to_screen_name:'kaleycuoco', handle:'kunalnayyar', id: { $gt: 0 } } ], })

关于php - MongoDB 记录太多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11701103/

相关文章:

php - 如何在nodejs中实现 "gzencode"(PHP函数)

node.js - 如何将 meteor 助手存储在 mongoDB 集合中,以及如何从 mongoDB 集合中呈现它

node.js - MongoDB 查询返回空数组

mongodb - 如何在 MongoDB 聚合框架中处理除以零

mongodb - 在 MongoDB 中中止 reIndex() 命令后解锁集合?

java - mongodb游标异常 - Java

php - yii 如何显示带有验证失败消息的自定义错误消息

php - 使用条件在smarty中设置var

php - FFMpeg:将图像转换为视频

PHP: fopen: 没有那个文件或目录