当前位置

网站首页> 程序设计 > 开源项目 > 程序开发 > 浏览文章

MongoDB入门之索引(一) - cnio

作者:小梦 来源: 网络 时间: 2024-08-08 阅读:

索引就像书的目录,如果查找某内容在没有目录的帮助下,只能全篇查找翻阅,这导致效率非常的低下;如果在借助目录情况下,就能很快的定位具体内容所在区域,效率会直线提高。

首先打开命令行,输入mongo。默认mongodb会连接名为test的数据库。

?  ~  mongoMongoDB shell version: 2.4.9connecting to: test> show collections> 

可以使用show collections/tables查看数据库为空。

然后在mongodb命令行终端执行如下代码

> for(var i=0;i<100000;i++) {... db.users.insert({username:'user'+i})... }> show collectionssystem.indexesusers> 

再查看数据库发现多了system.indexesusers两个表,前者即所谓的索引,后者为新建的数据库表。
这样user表中即有了10万条数据。

> db.users.find(){ "_id" : ObjectId("5694d5da8fad9e319c5b43e4"), "username" : "user0" }{ "_id" : ObjectId("5694d5da8fad9e319c5b43e5"), "username" : "user1" }{ "_id" : ObjectId("5694d5da8fad9e319c5b43e6"), "username" : "user2" }{ "_id" : ObjectId("5694d5da8fad9e319c5b43e7"), "username" : "user3" }{ "_id" : ObjectId("5694d5da8fad9e319c5b43e8"), "username" : "user4" }{ "_id" : ObjectId("5694d5da8fad9e319c5b43e9"), "username" : "user5" }

现在需要查找其中任意一条数据,比如

> db.users.find({username: 'user1234'}){ "_id" : ObjectId("5694d5db8fad9e319c5b48b6"), "username" : "user1234" }

发现这条数据成功找到,但需要了解详细信息,需要加上explain方法

> db.users.find({username: 'user1234'}).explain(){    "cursor" : "BasicCursor",    "isMultiKey" : false,    "n" : 1,    "nscannedObjects" : 100000,    "nscanned" : 100000,    "nscannedObjectsAllPlans" : 100000,    "nscannedAllPlans" : 100000,    "scanAndOrder" : false,    "indexOnly" : false,    "nYields" : 0,    "nChunkSkips" : 0,    "millis" : 30,    "indexBounds" : {},    "server" : "root:27017"}

参数很多,目前我们只关注其中的"nscanned" : 100000"millis" : 30这两项。
nscanned表示mongodb在完成这个查询过程中扫描的文档总数。可以发现,集合中的每个文档都被扫描了,并且总时间为30毫秒。
如果数据有1000万个,如果每次查询文档都被遍历一遍,时间也是相当可观。

对于此类查询,索引是一个非常好的解决方案。

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

然后再查找user1234

> db.users.ensureIndex({"username": 1})> db.users.find({username: 'user1234'}).explain(){    "cursor" : "BtreeCursor username_1",    "isMultiKey" : false,    "n" : 1,    "nscannedObjects" : 1,    "nscanned" : 1,    "nscannedObjectsAllPlans" : 1,    "nscannedAllPlans" : 1,    "scanAndOrder" : false,    "indexOnly" : false,    "nYields" : 0,    "nChunkSkips" : 0,    "millis" : 0,    "indexBounds" : {        "username" : [[    "user1234",    "user1234"]        ]    },    "server" : "root:27017"}

的确有点不可思议,查询在瞬间完成,因为通过索引只查找了一条数据,而不是100000条。

当然使用索引是也是有代价的:对于添加的每一条索引,每次写操作(插入、更新、删除)都将耗费更多的时间。这是因为,当数据发生变化时,不仅要更新文档,还要更新级集合上的所有索引。因此,mongodb限制每个集合最多有64个索引。通常,在一个特定的集合上,不应该拥有两个以上的索引。

小技巧

如果一个非常通用的查询,或者这个查询造成了性能瓶颈,那么在某字段(比如username)建立索引是非常好的选择。但只是给管理员用的查询(不太在意查询耗费时间),就不该对这个字段建立索引。

热点阅读

网友最爱