所以我有一个MongoDB实例,我试图用另一个集合中的数据更新一个集合中的数据。这两个集合是participants
,包含大约180,000个文档,questions
包含大约95,000个文档。
participants
中的文档通常如下所示:
{
"_id" : ObjectId("52f90b8bbab16dd8594b82b4"),
"answers" : [
{
"_id" : ObjectId("52f90b8bbab16dd8594b82b9"),
"question_id" : 2081,
"sub_id" : null,
"values" : [
"Yes"
]
},
{
"_id" : ObjectId("52f90b8bbab16dd8594b82b8"),
"question_id" : 2082,
"sub_id" : 123,
"values" : [
"Would prefer to go alone"
]
},
{
"_id" : ObjectId("52f90b8bbab16dd8594b82b7"),
"question_id" : 2082,
"sub_id" : 456,
"values" : [
"Yes"
]
}
],
"created" : ISODate("2012-03-01T17:40:21Z"),
"email" : "anonymous",
"id" : 65,
"survey" : ObjectId("52f41d579af1ff4221399a7b"),
"survey_id" : 374
}
我正在使用以下查询来执行更新:
db.participants.ensureIndex({"answers.question_id": 1, "answers.sub_id": 1});
print("created index for answer arrays!")
db.questions.find().forEach(function(doc){
db.participants.update(
{
"answers.question_id": doc.id,
"answers.sub_id": doc.sub_id
},
{
$set:
{
"answers.$.question": doc._id
}
},
false,
true
);
});
db.participants.dropIndex({"answers.question_id": 1, "answers.sub_id": 1});
但这需要大约20分钟才能运行。我希望添加索引有助于提高性能,但它仍然很慢。考虑到我正在索引对象数组中的字段,这个索引是否正确设置?谁能看到我正在做的任何会导致缓慢的事情?关于从哪里开始寻求提高此查询性能的建议?
答案 0 :(得分:1)
我认为您需要考虑实际在此做什么,以便理解为什么索引没有帮助,以及为什么这个操作需要这么长时间。
答案的第一部分是通过你在这里做的来解释的:
db.questions.find()
现在,仅此部分基本上表示您要求检索questions
集合中的每个文档。因此,我们可以看到您要执行的操作正是如此,因为您希望将该内容更新到participants
集合中,尤其是“问题”的文档_id。但是在这里,根据获取所有文档的定义,不会使用任何索引。
所以你正在做的是循环questions
中的每个文档,然后通过更新操作询问匹配 participants
记录来自“问题”的数据。这意味着你将所有95K文件“通过电线”拉回来,并通过“线路”发回你的更新操作,95K次。这不会发生在服务器上,并且您的应用程序和MongoDB之间存在网络流量。
索引本身除了改进每个participants
记录的搜索之外不会做太多,这比扫描更好,你应该得到匹配。但这不是花时间的部分,而是questions
的最大问题。另请注意,如果您要更新
因此,如果可以在与MongoDB服务器的网络术语尽可能接近的计算机上运行更新过程,那么这将是您最佳的性能改进。如果你想要有点大胆和/或可以检查另一个操作中的完整性,你也可以收回你的Write Concern,这将减少你的网络流量并等待对更新的响应(这是如果你把它放在“ fire and forget ”模式中。
如果您不确定概念,请参阅指南:
答案 1 :(得分:0)
如果有人感兴趣,我可以在选择questions
文档时使用投影,将此更新查询的运行时间从20分钟缩短到大约一分半钟。由于我仅使用_id
,id
和sub_id
字段,因此我能够执行以下操作:
db.questions.find({},{_id: 1, id: 1, sub_id: 1}).forEach(function(doc){
....
其中性能大幅提升。希望这有助于某人!