我有一个与MongoDB交互的PHP应用程序。直到最近,该应用程序运行良好,但几天前我发现该应用程序的响应开始非常缓慢。其中一个收藏已飙升至50万张以上的唱片。因此,该集合上任何查询的MongCursor都会超时。
我不认为50万张唱片太多。其他使用mongodb的页面也开始放慢速度,但不如使用具有50万条记录的集合的页面慢。不与MongoDB交互的静态页面仍然可以快速响应。
我不确定这里的问题是什么。我已经为集合编制了索引,所以这似乎不是问题。另一点需要注意的是,服务器上的RAM规格是512MB,当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
]
]
}
}
这个查询使用了不区分大小写的正则表达式,这不会有效地使用索引(尽管在本例中实际上没有定义索引)。
建议方法:
为搜索目的创建小写
handle_lc
和inreply_lc
字段在上面添加一个复合索引:
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 } }
],
})
是的,500K+应该可以。。据我所知,一个集合中的文档数量没有真正的"限制"。。可能是MongoDB可以生成的_id字段的唯一组合数。。但这将远远超过50万。。在你的情况下,我怀疑的是,也许你的询问不是很有选择性。因此,当集合中的文档较少时,您不会注意到这个问题。但随着增长,它似乎突然变得迟钝了。。比如,MongoCursor返回了多少文档?