mongodb的索引
1, 基本概念
索引就是用来加速查询的。有了索引就不需要再遍历整个集合,而是根据索引项直接跳转到文档位置。
.建立索引的基本方法是使用:ensureIndex函数,语法和sort函数相同:
db.p.ensureIndex({"username":1})
.可以建立多个字段的索引,但同一个字段的索引只需建立一次,多次建立无效。
db.p.ensuerIndex({"username":1, "age":-1})
.当建立了一个键的索引,对该键的查询得到优化,但对其他键可能没有用,所以要建立所有查询键的索引。
db.p.find({"username": "t1", "age":{"$gt":20}})
.建立索引要根据实际情况,不能一概而论,否则会起到反作用。创建索引的缺点就是每次插入和更新,删除时都会产生额外的开销。因此,要尽可能少的创建索引。一般来说若要返回一个表一半以上的记录,不使用索引要比使用索引快一些。
2,扩展索引
在建立索引要考虑以下的问题:
(1) 要做什么样的查询?哪些键需要索引?
(2)每个键的索引方向是怎样的?
(3)如何应对扩展?有没有不同键的排列可以使常用数据更多的保留在内存中?
如:要查询用户最近的记录:
db.users.ensureIndex({username:1, date:-1})
上面的这种方式就不是很好,会造成很多的内存交换吗,可以使用以下方式:
db.users.ensureIndex({date: -1, username:1})
.文档索引
索引可以任何类型的字段甚至文档:
> db.cc.insert( { name: "hh", addr: { city: "bj", state: "BJ" } } ); //插入记录
> db.cc.ensureIndex( { addr : 1 } ); //创建文档索引
> db.cc.find( { addr: { city: "bj", state: "BJ" } } ); //使用索引
{ "_id" : ObjectId("4f7257b862969873692a66cf"), "name" : "hh", "addr" : { "city" : "bj", "state" : "BJ" } }
> db.cc.find( { addr: { state: "BJ" , city: "bj"} } ); //该命令不会使用上面的索引,因为文档的顺序不一样
.为排序创建索引
> db.c.ensureIndex({x:-1}) //降序创建索引
> db.c.find().sort({x:-1}) //降序排列结果
.唯一索引
只需在ensureIndex 命令中指定”unique:true”即可创建唯一索引,确保集合中的键值是唯一的。
> db.c.insert({"test":"data"})
> db.c.insert({"test":"data"})
> db.c.find({"test":"data"})
{ "_id" : ObjectId("4f7395cfc405e1891ffa97fb"), "test" : "data" }
{ "_id" : ObjectId("4f7395d0c405e1891ffa97fc"), "test" : "data" }
> db.c.ensureIndex({"test":1}, {"unique":true})
E11000 duplicate key error index: cc.c.$test_1 dup key: { : null }
可以看到,我们向集合中添加了两条一模一样的记录,在建立唯一索引时,报出了重复记录的错误。
.删除重复
可以用dropDups来删除重复文档,此命令会保存找到的第一个文档。
> db.c.ensureIndex({"test":1}, {"unique":true, "dropDups":true})
E11000 duplicate key error index: cc.c.$test_1 dup key: { : "data" }
> db.c.find({"test":"data"})
{ "_id" : ObjectId("4f7395cfc405e1891ffa97fb"), "test" : "data" }
报出了一个错误,但重复键已经被删除。
.组合索引
把各个键组合起来,建立一个索引
.explain
MongoDB 提供了一个 explain 命令让我们获知系统如何处理查询请求。利用 explain 命令,我们可以很好地观察系统如何使用索引来加快检索,同时可以针对性优化索引。
> db.blog.ensureIndex({"age":-1})
> db.blog.find({age:{$gt:40}},{"name":1}).explain()
{
"cursor" : "BtreeCursor age_-1", //使用的游标
"nscanned" : 1, //被扫描的文档数
"nscannedObjects" : 1,
"n" : 1, //返回的文档数
"millis" : 0, //执行时间,毫秒
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : { //所使用的索引
"age" : [
[
1.7976931348623157e+308,
40
]
]
}
}
.索引管理
.删除索引
dropIndexes()函数可以删除索引
.重新建立索引
可以先删除索引,再添加新的索引
db.runCommand("dropIndexes":"foo", "index":"name")
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/20498361/viewspace-719688/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/20498361/viewspace-719688/