您的位置:首页 > 数据库 > Mongodb

MongoDB基础之六 索引

2016-05-24 13:13 513 查看

 

一 . 索引概述和基本操作

1. 索引提高查询速度,降低写入速度,权衡常用的查询字段,不必在太多列上建索引
2. 在mongodb中,索引可以按字段升序/降序来创建,便于排序
3. 默认是用btree来组织索引文件,2.4版本以后,也允许建立hash索引.

常用命令:
查看当前索引状态: db.collection.getIndexes();

创建普通的单列索引:db.collection.ensureIndex({field:1/-1}); 1是升续 2是降续

删除单个索引
db.collection.dropIndex({filed:1/-1});

一下删除所有索引
db.collection.dropIndexes();

创建多列索引 db.collection.ensureIndex({field1:1/-1, field2:1/-1});

 

例子: 

> for (var i = 1;i<=1000;i++){
... db.stu.insert({sn:i,name:'student'+i})
... };
>
>
> db.stu.find().count();
1000
> db.stu.find({sn:99});
{ "_id" : ObjectId("574271a9addef29711337c28"), "sn" : 99, "name" : "student99" }
> db.stu.find({sn:99}).explain();
{
"cursor" : "BasicCursor", -- 无索引相当于mysql的全表扫描
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1000, -- 扫描了1000行
....

> db.stu.ensureIndex({sn:1}); --创建索引
> db.stu.find({sn:99}).explain();
{
"cursor" : "BtreeCursor sn_1", --使用了索引
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1, --只用扫描一行
...
}

> db.stu.getIndexes(); --查询索引
[
{
"v" : 1,
"key" : {
"_id" : 1 -- 默认创建 正序
},
"ns" : "test.stu",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"sn" : 1
},
"ns" : "test.stu",
"name" : "sn_1"
}
]

> db.stu.ensureIndex({sn:1,name:1});
>
>
> db.stu.getIndexes();
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "test.stu",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"sn" : 1
},
"ns" : "test.stu",
"name" : "sn_1"
},
{
"v" : 1,
"key" : {
"sn" : 1,
"name" : 1
},
"ns" : "test.stu",
"name" : "sn_1_name_1"
}
]

 

 

二. 子文档索引

     指向下级嵌套的文档的索引

> db.shop.insert({name:'Nokia',spc:{weight:120,area:'taiwan'}});
> db.shop.insert({name:'Nokia',spc:{weight:100,area:'korea'}});

> db.shop.find({'spc.area':'taiwan'});
{ "_id" : ObjectId("5743d662addef29711337fb0"), "name" : "Nokia", "spc" : { "weight" : 120, "area" : "taiwan" } }

> db.shop.ensureIndex({'spc.area,1'});
Tue May 24 12:29:58.823 SyntaxError: Unexpected token }
> db.shop.ensureIndex({'spc.area':1});
>
> db.shop.getIndexes();
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "test.shop",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"spc.area" : 1
},
"ns" : "test.shop",
"name" : "spc.area_1"
}
]
>

 

 

三.  唯一索引

> show tables;
shop
stu
system.indexes
>
>
> db.tea.insert({email:'a@163.com'})
> db.tea.insert({email:'b@163.com'})
>
> db.tea.getIndexes();
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "test.tea",
"name" : "_id_"
}
]
>
>
>
> db.tea.ensureIndex({email:1},{unique:true});
>
>
> db.tea.insert({email:'c@163.com'})
> db.tea.insert({email:'c@163.com'})
E11000 duplicate key error index: test.tea.$email_1 dup key: { : "c@163.com" }
>

 

 

四. 稀疏索引

稀疏索引的特点------如果针对field做索引,针对不含field列的文档,将不建立索引.
与之相对,普通索引,会把该文档的field列的值认为NULL,并建索引.
适宜于: 小部分文档含有某列时.

db.collection.ensureIndex({field:1/-1},{sparse:true})

 

-- 模拟数据
> db.tea.insert({});
> db.tea.find();
{ "_id" : ObjectId("5743d98aaddef29711337fb4"), "email" : "a@163.com" }
{ "_id" : ObjectId("5743d98daddef29711337fb5"), "email" : "b@163.com" }
{ "_id" : ObjectId("5743d9cfaddef29711337fb7"), "email" : "c@163.com" }
{ "_id" : ObjectId("5743dc98addef29711337fbc") }

--稀疏索引下查不到数据
> db.tea.ensureIndex({email:1},{sparse:true});
> db.tea.find({email:null});
>

> db.tea.dropIndexes();
{
"nIndexesWas" : 2,
"msg" : "non-_id indexes dropped for collection",
"ok" : 1
}

--普通索引能查到
> db.tea.ensureIndex({email:1});
> db.tea.find({email:null});
{ "_id" : ObjectId("5743dc98addef29711337fbc") }

 

 总结:
如果分别加普通索引,和稀疏索引,
对于最后一行的email分别当成null 和 忽略最后一行来处理.
根据{email:null}来查询,前者能查到,而稀疏索引查不到最后一行.

 

五. 创建哈希索引(2.4新增的)

哈希索引速度比普通索引快,但是,无能对范围查询进行优化.
适宜于---随机性强的散列

db.collection.ensureIndex({file:'hashed'});

> db.tea.ensureIndex({email:'hashed'});
> db.tea.find({email:'a@163.com'}).explain();
{
"cursor" : "BtreeCursor email_hashed",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"email" : [
[
NumberLong("2069420833715827975"),
NumberLong("2069420833715827975")
]
]
},
"server" : "localhost.localdomain:27017"
}
>

 

六. 重建索引

一个表经过很多次修改后,导致表的文件产生空洞,索引文件也如此.
可以通过索引的重建,减少索引文件碎片,并提高索引的效率.
类似mysql中的optimize table

db.collection.reIndex()

> db.tea.reIndex();
{
"nIndexesWas" : 2,
"msg" : "indexes dropped for collection",
"nIndexes" : 2,
"indexes" : [
{
"key" : {
"_id" : 1
},
"ns" : "test.tea",
"name" : "_id_"
},
{
"key" : {
"email" : "hashed"
},
"ns" : "test.tea",
"name" : "email_hashed"
}
],
"ok" : 1
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: