MongoDB基础(三)mongodb中的索引使用(一)

2015-07-24 06:48:57 · 作者: · 浏览: 5

?

MongoDB中的索引和其他数据库索引类似,也是使用B-Tree结构。MongoDB的索引是在collection级别上的,并且支持在任何列或者集合内的文档的子列中创建索引。

?

下面是官方给出的一个使用索引查询和排序的一个结构图。

\

?

所有的MongoDB集合默认都有一个唯一索引在字段“_id”上,如果应用程序没有为 “_id”列定义一个值,MongoDB将创建一个带有ObjectId值的列。(ObjectId是基于 时间、计算机ID、进程ID、本地进程计数器 生成的)

\

?

MongoDB 同样支持在一列或多列上创建升序或降序索引。

MongoDB还可以创建 多键索引、数组索引、空间索引、text索引、哈希索引,其属性可以是唯一性索引、稀疏性索引、TTL(time to live)索引。

?

索引的限制:

索引名称不能超过128个字符

每个集合不能超过64个索引

复合索引不能超过31列


?

MongoDB 索引语法

db.collection.createIndex({ : < 1 or -1 > })

db.collection.ensureIndex({ : < 1 or -1 > })

?

db.collection.createIndex( { "filed": sort } )

db.collection.createIndex( { "filed": sort , "filed2": sort } )

?

db.tab.ensureIndex({"id":1})

db.tab.ensureIndex({"id":1} ,{ name:"id_ind"})

db.tab.ensureIndex({"id":1,"name":1},{background:1,unique:1})

db.tab.ensureIndex( { "id" : "hashed" })

?

创建索引(两种方法)

?

?

filed :为键列

sort :为排序。1 为升序;-1为降序。

?

创建单列索引

创建索引并给定索引名称

后台创建唯一的复合索引

创建哈希索引

(更多参数 看文章底部)

db.tab.indexStats( { index: "id_ind" } )

db.runCommand( { indexStats: "tab", index: "id_ind" } )

db.tab.getIndexes()

db.system.indexes.find()

(前2个似乎不能用,官方文档解释)

(not intended for production deployments)

查看索引

db.tab.totalIndexSize();

查看索引大小

db.tab.reIndex()

db.runCommand({reIndex:"tab"})

重建索引

db.tab.dropIndex( )

db.tab.dropIndex("id_1")

db.tab.dropIndexes()

删除索引

为getIndexes看到的索引名称

删除所有索引(注意!)

?

?


?

?

索引性能测试:

?

查看索引是否生效,分析查询性能有没有提高。先插入10万数据到集合tab

?

for(var i=0;1<=100000;i++){

var value=parseInt(i*Math.random());

db.tab.insert({"id":i,"name":"kk"+i,"value":value});

}

?

不知道是不是虚拟机的原因,插入了10分钟都未完成!~

自己又打开文件夹查看,一直进不去文件夹。结果客户端连接断开了!~查看服务竟然停了!

\

?

重启服务,进去查看行数:96万!(过后再查看吧!就用这数据测试了!)

db.tab.find().count()


?

AnalyzeQuery Performance :http://docs.mongodb.org/manual/tutorial/analyze-query-plan/

分析函数

db.tab.find({"name":"kk50000"}).explain()

查询name=”kk50000”的执行分析

db.tab.find({"name":"kk50000"}).explain("queryPlanner")

db.tab.find({"name":"kk50000"}).explain("Verbosity")

db.tab.find({"name":"kk50000"}).explain("executionStats")

db.tab.find({"name":"kk50000"}).explain("allPlansExecution")

这3种方法执行结果完全包括上面这种的结果

db.tab.find({"name":"kk50000"}).explain() 结果做分析:

"cursor" : "BasicCursor",

"isMultiKey" : false,

"n" : 1,

"nscannedObjects" : 966423,

"nscanned" : 966423,

"nscannedObjectsAllPlans" : 966423,

"nscannedAllPlans" : 966423,

"scanAndOrder" : false,

"indexOnly" : false,

"nYields" : 7555,

"nChunkSkips" : 0,

"millis" : 4677,

"server" : "kk-ad:27017",

"filterSet" : false

游标类型。BasicCurso(扫描), BtreeCursor(索引)

是否多键(组合)索引

返回行数

扫描行数

扫描行数

所有计划扫描的次数

所有计划扫描的次数

是否在内存中排序

?

?

?

耗时(毫秒)

服务器

?


?

现在创建索引:

db.tab.createIndex({"name":1})

\

?

db.tab.find({"name":"kk50000"}).explain() 使用索引的结果

"cursor" : "BtreeCursor name_1",

"isMultiKey" : false,

"n" : 1,

"nscannedObjects" : 1,

"nscanned" : 1,

"nscannedObjectsAllPlans" : 1,

"nscannedAllPlans" : 1,

"scanAndOrder" : false,

"indexOnly" : false,

"nYields" : 0,

"nChunkSkips" : 0,

"millis" : 1,

"indexBounds" : {

"name" : [

[

"kk50000",

"kk50000"

]

]

},

"server" : "kk-ad:27017",

"filterSet" : false

游标使用索引BtreeCursor = name_1

?

?

?

?

?

?

?

?

?

?

耗时:1毫秒

?

?

?

?

?

?

?

?

?

?


?

?

上面可以看到,没使用索引时,耗时4677毫秒,使用索引后,1毫秒!~并且不用全文档扫描。


?

索引提示(hint),当前collection创建的索引:

db.tab.ensureIndex({"id":1} ,{name:"id_ind"})

db.tab.ensureIndex({"id":1,"name":1},{background:1,unique:1