mongodb索引讲解与优化

语句集合

语句 功能 备注
db.name. getIndexes() 查询索引
db.name.totalIndexSize() 查询索引大小
db.name.dropIndex("indexName") 删除索引
db.name.dropIndex(‘*’) 删除name集合中的所有索引 _id索引不会删除
没有修改索引的方法 如果想想修改索引 先删除旧索引,再重新创建索引
db.name.ensureIndex() 创建索引

索引种类

种类 解释 备注
默认索引 Mongodb每个collection都会有一个默认主键_id,这个不能删除、也不会更名。当collection创建后,系统会自动创建一个”id”的索引,这个也是无法删除与更名的
单列索引 在单个栏位上创建的索引 eg:需要对Mail的read创建升序索引:db.Mail.ensureIndex({‘read’:1})
组合索引 对多个键创建的索引 eg:需要对Mail的user与folderId创建降序索引:db.Mail.ensureIndex({‘user’:-1,’folderId’:-1})
子文档索引 可以为内嵌文档的键创建索引,这种与普通索引没有什么区别 eg:需要对Mail中的attachments下的filename创建索引: db.Mail.ensureIndex({‘attachments.filename’:1})
注意:attachments.filename必须位于’’之中,否则会报错
唯一索引 唯 一索引可能确保collection的每一个document指定的键的唯一性。当文档不存在指定键时,会被认为键值是“null”,所以“null”也 会被认为是重复的,所以一般被作为唯一索引的键,最好都要有键值对 要保证Mail中每个用户的mailfilename的唯一性:db.Mail.ensureIndex({‘user’:1,‘filename’:1},{name:’index1’,‘unique’:true})

当为已有的collection增加唯一索引时,可能会有数据已经重复了。有时候可能希望将所有包含重复的文档都删除,可能在创建唯一索引时,使用dropDups选项:
db.Mail.ensureIndex({‘user’:1,‘filename’:1},{‘unique’:true,’dropDups’:true})
这个会将重复的数据只保留一份,不过有点鲁莽,如果数据很重要的话,建议不好这样做。

注意了:
Insert并不检查文档是否插入过,所以确保数据的唯一性,可能要用安全模式插入才行。这样,在插入时,如果有重复就会有错误提醒
Sparse索引 Sparse index解决索引文件过大的问题,有时候我们要索引的某个属性并非是所有记录都有,普通的索引是将所有的记录都包含进来,而sparse索引则仅包含含 有这个属性的记录,它不会对该项值为空的行作索引。这样就大大减小了某些列的索引大小。目前的限制是,sparse index只能包含一个属性。 eg:在Mail中有个标签属性labels,这个属性是唯一的,且有值的情况也不多,这种情况就最适合用sparse索引 了,创建索引的命令为:
db.Mail.ensureIndex({labels:1},{sparse:true})
Covered 索引 如果你查找的值正好是在索引中,则可以直接返回索引中存的值,而不用到数据文件中查找。(这个在传统关系型数据库中也有实现),不过,必须满足以下条件:
1:必须提供准备的返回字段,以便可以直接从索引库中查询
2:必须明确地排除使用_id字段{_id:0}当用explain时,当indexOnly=true,表示有用到covered index
// do a login with a covered index, returning the users roles/groups
> db.users.ensureIndex( { username : 1, password : 1, roles : 1} );
> db.users.save({username: "joe", password: "pass", roles: 2})
> db.users.save({username: "liz", password: "pass2", roles: 4})
> db.users.find({username: "joe"}, {_id: 0, roles: 1})
{ "roles" : 2 }
> db.users.find({username: "joe"}, {_id: 0, roles: 1}).explain()
{
"cursor" : "BtreeCursor username_1_password_1_roles_1",
...
"indexOnly" : true,
...
}

索引触发条件

索引命中:

假设索引为:

{a:1,b:1,c:1,d:1}:

实际上是有了下列索引

{a:1},{a:1,b:1},{a:1,b:1,c:1},{a:1,b:1,c:1,d:1}

但是使用{b:1}、{a:1,c:1}等索引的查询是会被优化的,只有使用索引前部的查询才能使用该索引。

Mongodb的查询优化器会重排查询项的顺序,以便命中索引,比如:查询{x:’a’,y:’b’}的时候,如果已有了{y:1,x:1}的索引,mongodb也会自己找到并命中的。

创建索引的缺点是每次插入、更新与删除时都会产生额外的开销,这是因为数据库不但需要执行这些操作,还是处理索引,因些,要尽量可能少创建索引。每个集合默认的最大索引个数为64个。

查询时,不要使用$ne or $nin,这样不能命中索引

使用explain查看

新版explain使用说明

db.collection.find(query).explain();

返回的信息如下

{“cursor” : “BasicCursor”,

“indexBounds” : [ ],

“nscanned” : 57594,

“nscannedObjects” : 57594,

“nYields” : 2 ,

“n” : 3 ,

“millis” : 108,

“indexOnly” : false}

现实结果可以得知cursor的类型,DB扫描的数据数,返回的数据数,还有执行的毫秒数。

“cursor” : “BasicCursor”:

命中的索引,当为BasicCursor时表示没有命中任何索引

indexBounds: 所使用的索引,被设置为表示为索引扫描的关键边界。

nscanned – 扫描的数据条数。

nscannedObjects – 扫描对象的数。

nYields – 查询所产生的锁的个数。

isMultiKey- MongoDB中提供了可以自动索引数组对象的值

If true, a multikey index was used.

n- 返回文档的数量

millis- 数据库中执行查询的时间

indexOnly – 是否使用了covered index。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容