我有一个与MongoDB交互的PHP应用程序。直到最近,该应用程序工作正常,但几天前我发现应用程序开始响应真的很慢。其中一个系列已达到500K +记录。因此MongCursor对该集合的任何查询都会保持超时。
我不认为500K记录是太多了。使用mongodb的其他页面也开始变慢,但没有使用具有500k记录的集合的页面。不与MongoDB交互的静态页面仍然可以快速响应。
我不确定这里会出现什么问题。我已将索引编入索引,因此这似乎不是问题。另一点需要注意的是服务器上的RAM规格是512 MB,当PHP执行Mongo时,top命令显示15000k内存空闲。
任何帮助将不胜感激。
答案 0 :(得分: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
]
]
}
}
此查询使用的case-insensitive regular expressions无法有效使用索引(虽然在这种情况下实际上没有定义)。
建议的方法:
为搜索目的创建小写handle_lc
和inreply_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 } }
],
})
答案 1 :(得分:0)
是的,500K +应该没问题。据我所知,对集合中的文档数量没有真正的“限制”......可能是MongoDB可以生成的_id字段的唯一组合数量。但是将大于500K ..在你的情况下,我怀疑,也许你的查询不是很有选择性。因此,当集合中的文档较少时,您没有注意到该问题。但随着增加,它似乎突然变得缓慢......就像MongoCursor返回了多少文件?