var i = 1,
nodes = 8;
setInterval(function(){
var rotation = i * 360 / nodes;
i = i + 1;
$('.cm').css({
'transform': 'rotate(' + rotation + 'deg)'
}).attr('data-rotation', rotation);
$('.cm li').each(function (node){
r = (node) * 360/nodes;
$($('.cm li')[node]).find('span').css({
'transform': 'rotate(' + ((rotation*-1) - r) + 'deg)'
});
});
if(i >= nodes){
i = 0;
}
}, 1000);
正如我所说,我跑了
db.users.find({role:'seeker'}, {
"email": 1,
"name": 2
})
得到这个
db.users.find({role:'seeker'}).explain()
如果我使用上面的查询,则需要15-20秒才能响应。我需要每天向批量用户发送电子邮件广告系列。我有一个node.js任务来执行此操作,当此任务在后台运行时,即使node.js不应该阻塞,它也会减慢其他所有内容
答案 0 :(得分:1)
我认为你做得对。就像select email, name from student where role='student'
你有多少条记录?你有没有调整/ profile你的mongoDB实例?
你有role
字段的索引吗?
db.users.createIndex( { role: 1 } )
create-an-index-to-support-read-operations
如果您的查询是否使用索引,则可以使用explain
获取一些信息。
对于无法使用索引的查询,MongoDB必须扫描所有文档 在与该查询匹配的文档的集合中。
如果每次都可以在您的应用中引入缓存,那么电子邮件列表是否相同?
答案 1 :(得分:0)
好的,所以在添加索引之后,解释看起来是正确的,并且确实使用了索引:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "users",
"indexFilterSet" : false,
"parsedQuery" : {
"role" : {
"$eq" : "seeker"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"role" : 1
},
"indexName" : "role_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"role" : [
"[\"seeker\", \"seeker\"]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 850834,
"executionTimeMillis" : 13217,
"totalKeysExamined" : 850834,
"totalDocsExamined" : 850834,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 850834,
"executionTimeMillisEstimate" : 1970,
"works" : 941141,
"advanced" : 850834,
"needTime" : 0,
"needFetch" : 90306,
"saveState" : 93946,
"restoreState" : 93946,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 850834,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 850834,
"executionTimeMillisEstimate" : 560,
"works" : 850834,
"advanced" : 850834,
"needTime" : 0,
"needFetch" : 0,
"saveState" : 93946,
"restoreState" : 93946,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"role" : 1
},
"indexName" : "role_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"role" : [
"[\"seeker\", \"seeker\"]"
]
},
"keysExamined" : 850834,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0
}
}
},
"serverInfo" : {
"host" : "xxx",
"port" : 12345,
"version" : "3.0.12",
"gitVersion" : "33934938e0e95d534cebbaff656cde916b9c3573"
},
"ok" : 1
}
我认为通过“一次检索所有”可以获得最快的效果。 我想知道你是否可以retrieve only specific fields,例如'name'和'email':
如果未指定投影,则find()方法将返回所有字段 与查询匹配的所有文档。
db.inventory.find({type:'food'})此操作将全部返回 库存集合中的文档类型的值 田地是'食物'。返回的文档包含所有字段。
因此,如果您不希望mongo返回每个学生的所有字段,只需传递一些其他参数,如下所示:
db.users.find( { role: 'student' }, { name: 1, email: 1, _id:0 } )
显然,从硬盘中读取所有字段是一项耗时的操作,因此从10中仅检索2个字段将为您的查询提供显着的提升。就sql而言,它是:select * from T
和select name from T
之间的区别。
我想知道您是否考虑使用分页和批处理获取/发送,即检索前10000名学生,发送电子邮件然后检索下一个10000名学生,发送电子邮件,重复...?
您还可以尝试通过在mongo数据库实例中对用户进行分片来进行水平扩展,但这取决于您的硬件功能,我不认为如果您只有一台服务器,它将为您带来任何好处。因此,分页应该是一种方法。