第一部分 插入测试数据
#时间稍长
for(var i = 0; i < 200000; i++){
db.numbers.insert({"num": i});
}
验证结果
> db.numbers.find().count() 200000
第二部分 索引前奏
2.1 monogo关键字explain()
explain()可以查看我们执行命令的内部实现,那么我们先看一下,再没有加索引之前,查询一条数据所需要的时间
/扫描
等字段
没有对比就没有伤害
没有伤害哪来的动力
首先我们查阅官网中对explain()的介绍,在此它有个参数--verbose[冗长],往下看,发现verbose中又有三个可选参数
1. queryPlanner: 默认model, 也就是执行的计划; 2. executionStats: 打印执行的状态; 3. allPlansExecution: 打印所有的执行的状态.
返回的结果又有哪些呢?真是一个问题接着一个问题
继续往下走,摘录一段英文
Output cursor.explain() operations can return information regarding: 1. queryPlanner, which details the plan selected by the query optimizer and lists the rejected plans; 2. executionStats, which details the execution of the winning plan and the rejected plans; and 3. serverInfo, which provides information on the MongoDB instance.
也就是最多返回三个大的字段,
1. queryPlanner: 查询优化器选择的计划细节,列出了拒绝计划; 2. executionStats: 成功的执行计划细节和拒绝计划; 3. serverInfo: 提供了MongoDB实例的信息。
Mongo官网explain返回说明
有了之上的explain()的主要的使用说明, 那么就可以继续往下继续了.
第三部分 索引
3.1 查询
未加索引的查询
#插叙最后3条数据
> db.numbers.find({"num": {"$gt": 199996}}).explain("executionStats") {
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.numbers",
"indexFilterSet" : false,
"parsedQuery" : {
"num" : {
"$gt" : 199996 } },
"winningPlan" : {
#全文扫描 "stage" : "COLLSCAN",
"filter" : {
"num" : {
"$gt" : 199996 } },
"direction" : "forward" },
"rejectedPlans" : [ ] },
"executionStats" : {
"executionSuccess" : true, #返回3个字段 "nReturned" : 3, #花费时间[毫秒] "executionTimeMillis" : 92, #扫描到的索引 "totalKeysExamined" : 0, #与之前返回字段[nscannedObjects]一致, #查询的个数 "totalDocsExamined" : 200000, "executionStages" : { #全文扫描 "stage" : "COLLSCAN", "
filter" : {
"num" : {
"$gt" : 199996 } },
"nReturned" : 3,
## 该查询根据index去检索获取具体数据的时间 "executionTimeMillisEstimate" : 47,
"works" : 200002,
"advanced" : 3,
"needTime" : 199998,
"needYield" : 0,
"saveState" : 1562,
"restoreState" : 1562,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 200000 } }, "serverInfo" : {
"host" : "huanghaowei.local",
"port" : 27017,
"version" : "3.4.0",
"gitVersion" : "f4240c60f005be757399042dc12f6addbc3170c1" },
"ok" : 1 }
3.2 添加索引
> db.numbers.ensureIndex({"num": 1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.numbers.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.numbers"
},
{
"v" : 2,
"key" : {
"num" : 1
},
"name" : "num_1",
"ns" : "test.numbers"
}
]
>
3.3 验证
其中关于时间的字段少了不是一点的量,当然你也会发现其中,多了好多个字段,先不说其他的,这个时间量
就完全可以俘获你的芳心吧 -.__.-
> db.numbers.find({"num": {"$gt": 199996}}).explain("executionStats")
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.numbers",
"indexFilterSet" : false,
"parsedQuery" : {
"num" : {
"$gt" : 199996
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : { #索引扫描
"stage" : "IXSCAN",
"keyPattern" : {
"num" : 1
},
"indexName" : "num_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"num" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"num" : [
"(199996.0, inf.0]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 3, #可以对比一下这几个字段
"executionTimeMillis" : 7, #仅此为我们需要的数据条数
#nReturned=totalKeysExamined=totalDocsExamined(需要具体情况具体分析)
"totalKeysExamined" : 3,
"totalDocsExamined" : 3,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 3,
"executionTimeMillisEstimate" : 0,
"works" : 4,
"advanced" : 3,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 3,
"alreadyHasObj" : 0,
"inputStage" : {
##索引扫描
"stage" : "IXSCAN",
"nReturned" : 3,
"executionTimeMillisEstimate" : 0,
"works" : 4,
"advanced" : 3,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"num" : 1
},
"indexName" : "num_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"num" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"num" : [
"(199996.0, inf.0]"
]
},
"keysExamined" : 3,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}, "serverInfo" : {
....
}, "ok" : 1
}
>
3.4 删除索引
不在需要的索引,我们可以将其删除。删除索引时,可以删除集合中的某一索引,可以删除全部索引。
3.4.1 删除指定的索引dropIndex()
db.COLLECTION_NAME.dropIndex("INDEX-NAME")
删除指定的索引
db.numbers.dropIndex("num")
删除所有索引dropIndexes()
> db.numbers.dropIndexes()
相对数据集与复杂程度都属于入门,下篇继续.