MongoDB学习(五)
索引
MongoDB的索引采用了B树,索引能有效的提高查询效率。创建索引的查询的时间复杂度为logN,相当于做了一次二分法。MongoDB在执行查询时,如果有索引会走一次索引的选择,选择最优的索引情况,最终去执行查询再将结果返回。
在使用MongoDB时,理论上所有的查询都应该落在索引上,除非数据很少,可以不落在索引。所以在开发时,有需求到来,首先要去看一下执行计划,检查自己的语句是否有问题。以下为返回的实例,并在关键参数后面增加了注释
// db.user.find({user_no:"000000"}).explain(true)
{
...
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 4,
"executionTimeMillis" : 54,//本次查询耗费的时间
"totalKeysExamined" : 0,
"totalDocsExamined" : 103190,//本次查询扫描的文档数
"executionStages" : {
"stage" : "COLLSCAN", //索引扫描
"filter" : {
"user_no" : {
"$eq" : "000000"
}
},
"nReturned" : 4,
"executionTimeMillisEstimate" : 0,
"works" : 103192,
"advanced" : 4,
"needTime" : 103187,
"needYield" : 0,
"saveState" : 806,
"restoreState" : 806,
"isEOF" : 1,
"direction" : "forward",
"docsExamined" : 103190
},
"allPlansExecution" : [ ]
}
...
}
本次查询时合理的应该在user_no字段上面设置索引。
设置索引
常见的MongoDB的索引类型有如下几种
-
单键索引
-
组合索引
设置组合索引最好满足esr原则,精确匹配的字段放在最前面,排序的字段放到中间,范围的字段放在最后面。比如说一个查询
db.test.find({gender:"f",age:{$gte:18}}).sort("join_date":1)
应该如何设置索引。最好的方式是
db.test.createIndex({gender:1,join_date:1,age:1})
-
地理位置索引
地理位置索引也比较特殊,如果涉及到了地理位置业务,这种索引非常方便
db.geo_col.createIndex({location:"2d"},{min:-20,max:20,bits:10},{collation:{locale:"simple"}})
–查询
db.geo_col.find({location:{$geoWithin:{$box:[[1,1],[3,3]]}}})
-
全文索引
某些程度上可以替代elasticsearch
db.test.createIndex({'content':"text"})
–查询
db.test.find({$text:{$search:"coffee"}})
-
部分索引
非常实用的一种索引,可以将文档的部分进行过滤来创建索引,比如在a字段所有大于5的数据创建索引
db.test.createIndex({a:1},{partialFilterExpression:{a:{$gte:5}}})
索引的其他技巧
-
后台创建索引
db.test.createIndex({a:1},{background:true})
-
为不同的业务创建不同的索引
使用MongoDB一般都会使用集群,可以将某个从节点的索引与其他节点不同,然后处理特殊的业务,比如说报表,一般情况下报表的查询与业务都不一样
- 该从节点priority设置为0
- 关闭该从节点
- 以单机模式启动
- 添加索引
- 关闭从节点,以副本集模式启动