MongoDB 第11章 MongoDB 索引
1、简介
MongoDB提供了多样性的索引支持,索引信息被保存在system.indexes中,且默认总是为_id创建索引,它的索引使用基本和MySQL的关系型数据库一样,其实可以这样说说,索引是凌驾于数据存储系统之上的另外一层系统,所以各种结构迥异的存储都有相同或者相似的索引实现及使用接口并不足为奇。
2、基础索引
在字段age上创建索引,1(升序),-1(降序)
>db.user.ensureIndex({age:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.user.getIndexes();
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.user"
},
{
"v" : 1,
"key" : {
"age" : 1
},
"name" : "age_1",
"ns" : "test.user"
}
]
>
说明
上列中显示出来了一共有2个索引,其中_id是创建表的时候自动创建的索引,此索引是不能够被删除的。
当系统已有大量数据时,创建索引的过程是个非常耗时的过程,我们可以在后台执行,只需要制定background:true即可。
>db.user.ensureIndex({age:1},{background:true})
3、文档索引
索引可以任何类型的字段,甚至文档。
> db.factories.insert({name:"www",addr:{city:"BJ",state:"BEIJING"}});
WriteResult({ "nInserted" : 1 })
在addr列上创建索引
> db.factories.ensureIndex({addr:1});
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
下面的查询将会用到我们刚刚创建的索引
> db.factories.find({addr:{city:"BJ",state:"BEIJING"}});
{ "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } }
但是下面这个查询不会用到索引,因为查询的顺序跟索引建立的顺序不一样
> db.factories.find({addr:{state:"BEIJING",city:"BJ"}});
4、组合索引
跟其他数据库产品一样,MongoDB也是有组合索引的,下面我门将在addr.ctiy和addr.state上建立组合索引,当创建组合索引时,字段后面的1表示升序,-1表示降序,是用1还是用-1主要跟排序的时候或者指定范围内查询的时候有关的。
> db.factories.ensureIndex({"addr.city":1,"addr.state":1});
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
>
此时下面查询都用到了这个索引
> db.factories.find({"addr.city":"BJ","addr.state":"BEIJING"});
{ "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } }
>
<span style="font-family:SimHei;font-size:14px;">> db.factories.find({"addr.city":"BJ"});
{ "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } }
>
<span style="font-family:SimHei;font-size:14px;">> db.factories.find().sort({"addr.city":1,"addr.state":1});
{ "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } }
>
<span style="font-family:SimHei;font-size:14px;">> db.factories.find().sort({"addr.city":1})
{ "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } }
>
5、唯一索引
只需要在ensureIndex命令中指定unique:true即可创建唯一索引,比如往表t4中插入两条记录:
> db.t4.insert({firstname:"wang",lastname:"wu"});
WriteResult({ "nInserted" : 1 })
> db.t4.insert({firstname:"wang",lastname:"liu"});
WriteResult({ "nInserted" : 1 })
>
在t4表中建立唯一索引
> db.t4.ensureIndex({firstname:1,lastname:1},{unique:true});
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
查看索引:
> db.t4.getIndexes();
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.t4"
},
{
"v" : 1,
"unique" : true,
"key" : {
"firstname" : 1,
"lastname" : 1
},
"name" : "firstname_1_lastname_1",
"ns" : "test.t4"
}
]
6、强制使用索引
hint命令可以强制使用某个索引
> db.t5.insert({name:"wangwu",age:20});
WriteResult({ "nInserted" : 1 })
>
创建索引
> db.t5.ensureIndex({name:1,age:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
查询(没有使用索引)
> db.t5.find({age:{$lt:30}}).explain()
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"server" : "localhost.localdomain:27017",
"filterSet" : false
}
强制使用索引
> db.t5.find({age:{$lt:30}}).hint({name:1,age:1}).explain()
{
"cursor" : "BtreeCursor name_1_age_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 37,
"indexBounds" : {
"name" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"age" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : "localhost.localdomain:27017",
"filterSet" : false
}
7、删除索引
删除索引分为删除某张表的所有索引 和删除某张表的某个索引,具体如下:
> db.t5.dropIndexes();
{
"nIndexesWas" : 2,
"msg" : "non-_id indexes dropped for collection",
"ok" : 1
}
>
删除t4表中的firstname索引
> db.t4.dropIndex({firstname:1})
{
"nIndexesWas" : 2,
"ok" : 0,
"errmsg" : "can't find index with key:{ firstname: 1.0 }"
}
>
- 点赞
- 收藏
- 关注作者
评论(0)