您的位置:首页 > 大数据 > 人工智能

mongodb查询计划(explain)分析

2017-03-01 16:38 169 查看

环境

mongodb:3.4

robomongo:1.0.RC1

explain 返回的数据

执行的语句:

db.urlcontents.find({ir_urltitle:{$regex:"科技"}, ir_groupname:"产业热点" }).sort({ir_urltime:-1}).explain("queryPlanner")


结果为:

{
"cursor" : "BtreeCursor ir_groupname_1_ir_urltime_-1_ir_urltitle_1 multi"-索引名,
"isMultiKey" : false --- 是否使用多键索引,
"n" : 39 --- 返回的文档数量,
"nscannedObjects" : 39 --- Mongodb按照索引指针去磁盘上查找实际文档次数,
"nscanned" : 3103 --- 查找过的索引条目数,
"nscannedObjectsAllPlans" : 3144,
"nscannedAllPlans" : 12424,
"scanAndOrder" : false --- 是否在内存中排序,
"indexOnly" : false --- 是否使用了索引覆盖,
"nYields" : 0 --- 为了让写入请求能够顺利执行,本次查询暂停的次数,
"nChunkSkips" : 0,
"millis" : 36 --- 查询计划花费的总时间,
"indexBounds" : {
"ir_groupname" : [
[
"产业热点",
"产业热点"
]
],
"ir_urltime" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
],
"ir_urltitle" : [
[
"",
{}
],
[
/科技/,
/科技/
]
]
},
"server" : "10-10-114-219:27018"
}


覆盖索引 (indexOnly:true)

覆盖索引就是:当一个索引包含用户请求的所有字段,可以认为这个索引覆盖了本次查询。

所以在实际中,我们应该优先使用覆盖索引,而不是去获取实际的文档。这样可以保证工作集比较小,尤其与右平衡索引一起使用时。 ——《Mongodb权威指南》

由于mongodb默认返回的字段中包含
_id
字段,所以最好使用
投射
来指定不要返回
_id


如果一个查询使用的是覆盖索引,那么执行
explain()
时,
indexOnly
字段的值为
true


唯一索引

唯一索引可以确保集合的每一个文档的指定键都有唯一值。例如,如果想保证不同文档的
username
键拥有不同的值,创建一个唯一索引就好了:

>db.users.ensureIndex({"username":1},{"unique":true})


如果试图向上面的集合中插入如下文档:

>db.users.insert({username:"bob"})
>db.users.insert({username:"bob"})


会报错:E11000 duplicate key error index : test.users.$username_1 dup key :{:”bob”}

系统自动创建的
_id
就是唯一索引,这个唯一索引是不能被删除的,其他唯一索引可以删除。

复合唯一索引

在上面的基础上,创建多个键的所以即可。

比如:

{username:1, age:1}


稀疏索引

>db.test.ensureIndex({email:1},{unique:true, sparse:true})


上面的意思是:创建了一个可选的唯一索引,也就是说,
email
这个字段可以没有,如果有,则必须是唯一的,不能重复。而上面唯一索引,即便字段为null或不存在,也不允许重复出现。
sparse
选项是用来创建稀疏索引的。

注意:

稀疏索引不必是唯一的。只要去掉
unique
选项,就可以创建一个非唯一的稀疏索引。

零碎知识

一个查询执行一个索引

mongodb查询一般情况下,是一次查询只能使用一个索引,但是
$or
是个例外:

假设我们创建了所以
{x:1}
和索引
{y:1}


db.foo.find({"$or":[{'x':123},{"y":456}]})


这里执行两个索引,因为
Mongodb
是执行两次后查询后,把结果合并到一起的。

mongodb索引管理

mongodb索引统一在
system.indexes
集合中管理。

这个集合只能通过
ensureIndex
dropIndexes
来操作。

指定索引名

如果索引包含两个以上的键时,指定索引名称会更好看些。

>db.foo.ensureIndex({a:1,b:1,c:1,d:1},{"name":"自己取个名字"})


可以调用
getLastError
方法来查看索引是否创建成功。

查询索引信息

db.people.getIndexes()


删除索引

db.people.dropIndex("x_1_y_1")
{"nIndexesWas":3, "ok":1}


索引信息里的
name
字段就是该索引的唯一标识

创建索引,后台执行

db.people.ensureIndex({x:1,y:1},{background:1})
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: