索引为频繁的查询提供高性能读取操作。
默认情况,新添加文档会在_id字段创建一个索引。
首先,向新集合testindx中插入1百万个文档。
for(i=0;i<1000000;i++){
db.testindx.insert({"name":"user"+i,"age":Math.floor(Math.random()*120)})
}
执行结果:
然后,查询name值是user100的文档。并通过explain()分析执行过程。
db.testindx.find({"name":"user100"}).explain("allPlansExecution")
执行结果:
{
"queryPlanner" : {
"plannerVersion" : 1.0,
"namespace" : "xhb.testindx",
"indexFilterSet" : false,
"parsedQuery" : {
"name" : {
"$eq" : "user100"
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"name" : {
"$eq" : "user100"
}
},
"direction" : "forward"
},
"rejectedPlans" : [
]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1.0, //1.返回一个文档结果
"executionTimeMillis" : 650.0, //2.执行耗时650毫秒
"totalKeysExamined" : 0.0,
"totalDocsExamined" : 1000000.0, //3.检查了1百万个文档
"executionStages" : {
"stage" : "COLLSCAN", //4.扫描了整个集合
"filter" : {
"name" : {
"$eq" : "user100"
}
},
"nReturned" : 1.0,
"executionTimeMillisEstimate" : 548.0,
"works" : 1000002.0,
"advanced" : 1.0,
"needTime" : 1000000.0,
"needYield" : 0.0,
"saveState" : 7815.0,
"restoreState" : 7815.0,
"isEOF" : 1.0,
"invalidates" : 0.0,
"direction" : "forward",
"docsExamined" : 1000000.0
},
"allPlansExecution" : [
]
},
"serverInfo" : {
"host" : "tommy",
"port" : 27017.0,
"version" : "4.0.3",
"gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c"
},
"ok" : 1.0
}
重点关注:
单键索引
创建索引的模版语句:ensureIndex({"字段":1,"字段":-1,......},{其他约束,可忽略})
db.testindx.ensureIndex({"name":1})
上面的语句在文档的name字段上创建了一个索引。再执行一下上面的查询语句。
db.testindx.find({"name":"user100"}).explain("allPlansExecution")
执行结果:
{
"queryPlanner" : {
"plannerVersion" : 1.0,
"namespace" : "xhb.testindx",
"indexFilterSet" : false,
"parsedQuery" : {
"name" : {
"$eq" : "user100"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name" : 1.0
},
"indexName" : "name_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2.0,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"user100\", \"user100\"]"
]
}
}
},
"rejectedPlans" : [
]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1.0, //1.返回一个结果文档
"executionTimeMillis" : 1.0, //执行耗时1毫秒
"totalKeysExamined" : 1.0,
"totalDocsExamined" : 1.0, //检查了一个文档
"executionStages" : {
"stage" : "FETCH", //执行方式:提取
"nReturned" : 1.0,
"executionTimeMillisEstimate" : 0.0,
"works" : 2.0,
"advanced" : 1.0,
"needTime" : 0.0,
"needYield" : 0.0,
"saveState" : 0.0,
"restoreState" : 0.0,
"isEOF" : 1.0,
"invalidates" : 0.0,
"docsExamined" : 1.0,
"alreadyHasObj" : 0.0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1.0,
"executionTimeMillisEstimate" : 0.0,
"works" : 2.0,
"advanced" : 1.0,
"needTime" : 0.0,
"needYield" : 0.0,
"saveState" : 0.0,
"restoreState" : 0.0,
"isEOF" : 1.0,
"invalidates" : 0.0,
"keyPattern" : {
"name" : 1.0
},
"indexName" : "name_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2.0,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"user100\", \"user100\"]"
]
},
"keysExamined" : 1.0,
"seeks" : 1.0,
"dupsTested" : 0.0,
"dupsDropped" : 0.0,
"seenInvalidated" : 0.0
}
},
"allPlansExecution" : [
]
},
"serverInfo" : {
"host" : "tommy",
"port" : 27017.0,
"version" : "4.0.3",
"gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c"
},
"ok" : 1.0
}
重点关注:
由此可见,执行查询时扫描了整个集合,由于没有使用索引对性能造成了比较严重的影响。索引创建后,在查询执行时间方面产生了显著的差异。