MongoDB。如何设置索引?
问题描述:
请帮我用mongoDB中的索引。MongoDB。如何设置索引?
有一个收集了800,000个文件。 有一个很长时间的请求。大约5秒钟!
{
"$or":[
{
"performer":"534ba408f9cd0ecb51711673",
"$or":[
{
"performersRole":"534ba30bf9cd0ec151a69522"
},
{
"performersRole":{
"$exists":false
}
}
]
},
{
"performersRole":"534ba30bf9cd0ec151a69522",
"notShowInToDo":{
"$ne":true
}
}
],
"taskTime":{
"$gte":1409774400,
"$lt":1409860799
},
"$and":[
{
"$or":[
{
"department":{
"$in":[
"5356134ef9cd0e4805672a15",
"53561368f9cd0e4b05645f3f",
"53a0357ff9cd0e670537c4b7",
"53a03594f9cd0e6705389449"
]
}
},
{
"department":{
"$exists":false
}
}
]
},
{
"$or":[
{
"salon":"534f7b3bf9cd0e311e77896f"
},
{
"salon":{
"$exists":false
}
}
]
}
],
"isDone":{
"$ne":true
}
}
要添加哪些索引进行优化?感谢您的任何建议!
几乎快要这种格式的所有文件:
{
"_id": "541da66cf535a4a8569dd0ed",
"title": "test task",
"taskTime": NumberLong(1411229292),
"client": "53f876b2f535a4187f9e1264",
"salon": "534f7c3cf9cd0e91206dd948",
"track": "541da66cf535a4a8569dd0ec",
"department": "53a0357ff9cd0e670537c4b7",
"type": "invitePBP",
"performersRole": [
"534ba30bf9cd0ec151a69522"
],
"notShowInToDo": true,
"@createTime": NumberLong(1411229292),
"@updateTime": NumberLong(1411229292)
}
答
创建索引之前,请考虑以下几点:
1.砍倒查询层次尽可能你可以数;
2.如果可能,请避免使用$add
和$or
;
3.尽可能避免使用$exists
,因为它将访问该集合,即使在该字段上有索引;
4.根据您想要执行的顺序设计索引。
假设我有正确理解你的要求,那么我重构为下面的查询:
var query = {
"taskTime" : {
"$gte" : 1409774400,
"$lt" : 1409860799
},
"isDone" : {
"$ne" : true
},
"$and" : [
{
"salon" : {
"$in" : [ null, "534f7b3bf9cd0e311e77896f" ]
}
}, {
"department" : {
"$in" : [ null,
"5356134ef9cd0e4805672a15",
"53561368f9cd0e4b05645f3f",
"53a0357ff9cd0e670537c4b7",
"53a03594f9cd0e6705389449" ]
}
}],
"$or" : [ {
"performer" : "534ba408f9cd0ecb51711673",
"performersRole" : {
"$in" : [ null, "534ba30bf9cd0ec151a69522" ]
}
}, {
"performersRole" : "534ba30bf9cd0ec151a69522",
"notShowInToDo" : {
"$ne" : true
}
} ]
};
是null
小心:
- 是受到注目的是
{"salon" : {"$in" : [ null, "534f7b3bf9cd0e311e77896f" ]}
可以在指数{salon:1}
完全工作在v2.4中,但仍会访问v2.6中的集合,我不知道确切的原因,但只是猜测可能定义为null
已更改(包括undefined
类型)。 - 要避免v2.6中的这个问题,另一种方法是将实际值初始化为字段
salon
而不是无所事事。
您可以尝试用这种方法创建索引,并且由于我没有真实的数据来进行测试,所以您的反馈会被设置。
db.c.ensureIndex({taskTime:1, isDone:1, salon:1, department:1}, {name:"bigIndex"});
加入我的测试结果 - 1010,000文件
var a = {
"taskTime" : {
"$gte" : 1410443932781,
"$lt" : 1412443932781
},
"isDone" : {
"$ne" : true
},
"$and" : [
{
"salon" : {
"$in" : [ null, "534f7b3bf9cd0e311e77896f", "5420ecdc218ba2fb5353ad5b" ]
}
}, {
"department" : {
"$in" : [ null,
"5356134ef9cd0e4805672a15",
"53561368f9cd0e4b05645f3f",
"53a0357ff9cd0e670537c4b7", "5420ecdc218ba2fb5353ad5d",
"53a03594f9cd0e6705389449" ]
}
}],
"$or" : [ {
"performer" : "534ba408f9cd0ecb51711673",
"performersRole" : {
"$in" : [ null, "5420ecdc218ba2fb5353ad5e" ]
}
}, {
"performersRole" : "5420ecdc218ba2fb5353ad5e",
"notShowInToDo" : {
"$ne" : true
}
} ]
};
db.c.find(a).explain();
{
"cursor" : "BtreeCursor bigIndex",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 54290,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 54290,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 425,
"nChunkSkips" : 0,
"millis" : 261,
"indexBounds" : {
"taskTime" : [
[
1410443932781,
1412443932781
]
],
"isDone" : [
[
{
"$minElement" : 1
},
true
],
[
true,
{
"$maxElement" : 1
}
]
],
"salon" : [
[
null,
null
],
[
"534f7b3bf9cd0e311e77896f",
"534f7b3bf9cd0e311e77896f"
],
[
"5420ecdc218ba2fb5353ad5b",
"5420ecdc218ba2fb5353ad5b"
]
],
"department" : [
[
null,
null
],
[
"5356134ef9cd0e4805672a15",
"5356134ef9cd0e4805672a15"
],
[
"53561368f9cd0e4b05645f3f",
"53561368f9cd0e4b05645f3f"
],
[
"53a0357ff9cd0e670537c4b7",
"53a0357ff9cd0e670537c4b7"
],
[
"53a03594f9cd0e6705389449",
"53a03594f9cd0e6705389449"
],
[
"5420ecdc218ba2fb5353ad5d",
"5420ecdc218ba2fb5353ad5d"
]
]
},
"server" : "Mars-PC:27017",
"filterSet" : false
}
你最好提供更多的细节。例如,你制作了哪些索引?哪些字段有独特的价值? ... – Wizard 2014-09-20 16:09:47
添加到示例问题文档 – jeka5555 2014-09-20 16:31:40
除了非常奇怪的构造,你可能只是[阅读关于索引的文档](http://docs.mongodb.org/manual/core/indexes/)。 – 2014-09-21 09:56:18