MongoDB索引探究

来源:互联网 发布:985软件工程硕士工资 编辑:程序博客网 时间:2024/06/08 17:27

关于索引

索引通常能够极大的提高查询的效率。在系统中使用查询时,应该考虑建立相关的索引。在MongoDB中创建索引相对比较容易。MongoDB中的索引在概念上和大多数关系型数据库如MySQL是一样的;需要在MySQL中建立索引的情况, 一般同样适合于MongoDB。

为何需要索引

当数据保存在磁盘类存储介质上时,它是作为数据块存放。这些数据块是被当作一个整体来访问的,这样可以保证操作的原子性。硬盘数据块存储结构类似于链表,都包含数据部分,以及一个指向下一个节点(或数据块)的指针,不需要连续存储。

记录集只能在某个关键字段上进行排序,所以如果需要在一个无序字段上进行搜索,就要执行一个线性搜索(Linear Search)的过程,平均需要访问N/2的数据块,N是表所占据的数据块数目。如果这个字段是一个非主键字段(也就是说,不包含唯一的访问入口),那么需要在N个数据块上搜索整个表格空间。

但是对于一个有序字段,可以运用二分查找(Binary Search),这样只要访问log2 (N)的数据块。这就是为什么性能能得到本质上的提高。

什么是索引

索引是对记录集的多个字段进行排序的方法。在一张表中为一个字段创建一个索引,将创建另外一个数据结构,包含字段数值以及指向相关记录的指针,然后对这个索引结构进行排序,允许在该数据上进行二分法排序。

副作用是索引需要额外的磁盘空间,对于MySQL的MyISAM引擎而言,这些索引是被统一保存在一张表中的,这个文件将很快到达底层文件系统所能够支持的大小限制,如果很多字段都建立了索引的话。

索引策略

设计索引的一个通用策略就是在和您的产品中使用的数据集相似的数据集上,根据一系列不同的索引配置分别建立索引,考察哪一种配置性能最优。检查当前所创建的索引以确保您当前所使用和计划使用的查询。如果一个索引不再使用,应该删除它。

MongoDB索引

创建索引

mongodb采用ensureIndex来创建索引,如:

db.user.ensureIndex({"name":1})

表示在user集合的name键创建一个索引,这里的1表示索引创建的方向,可以取值为1和-1
在这里面,我们没有给索引取名字,mongodb会为我们取一个默认的名字,规则为keyname1_dir1_keyname2_dir2…keynameN_dirN
keyname表示键名,dir表示索引的方向,例如,上面的例子我们创建的索引名字就是name_1

组合索引

索引还可以创建在多个键上,也就是联合索引,如:

db.user.ensureIndex({"name":1,"age":1})

这样就创建了name和age的联合索引。

唯一索引

与RDB类似,我们也可以定义唯一索引,方法就是指定unique键位true:

db.user.ensureIndex({"name":1},{"unique":true})

_id 是创建表的时候自动创建的索引,此索引是不能够删除的。

后台创建

当系统已有大量数据时,创建索引就是个非常耗时的活,我们可以在后台执行,只需指定“backgroud:true”即可。

db.user.ensureIndex({age:1} , {backgroud:true})

在mongo2.4以前有一个bug,在主库发起后台创建索引,从库建索引时不是在后台,从而导致主从同步和访问数据的问题。

对于给定的某个操作,MongoDB只能使用 一个 索引来支持该操作。此外, $or 查询语句中的每个子句可能会使用不同的一个索引。

查看索引

索引的信息存在每个数据库的system.indexes集合里面,对这个集合只能有ensureIndex和dropIndexes进行修改,不能手动插入或修改集合。

通过> db.system.indexes.find()可以找到数据库中多有的索引:

db.system.indexes.find() 

删除索引

db.user.dropIndex({age:1} 

强制使用索引

hint 命令可以强制使用某个索引。

db.user.find({age:{$lt:30}}).hint({name:1, age:1}).explain()

索引排序

随着集合的增长,需要针对查询中大量的排序做索引。如果没有对索引的键调用sort,MongoDB需要将所有数据提取到内存并排序。因此在做无索引排序时,如果数据量过大以致无法在内存中进行排序,此时MongoDB将会报错。

使用explain:

MongoDB 提供了一个 explain 命令让我们获知系统如何处理查询请求。利用 explain 命令,我们可以很好地观察系统如何使用索引来加快检索,同时可以针对性优化索引。

> db.test.find().explain(){    "cursor" : "BasicCursor",    "nscanned" : 1,    "nscannedObjects" : 1,    "n" : 1,    "millis" : 0,    "nYields" : 0,    "nChunkSkips" : 0,    "isMultiKey" : false,    "indexOnly" : false,    "indexBounds" : {    }    }

explain会返回查询使用的索引情况,耗时和扫描文档数的统计信息。
“cursor”:”BasicCursor”表示没有使用索引。
“nscanned”:1 表示查询了多少个文档。
“n”:1 表示返回的文档数量。
“millis”:0 表示整个查询的耗时。

常用优化方案

  • 创建索引
  • 限定返回结果数
  • 只查询使用到的字段
  • 采用capped collection
  • 采用Server Side Code Execution
  • 使用Hint,强制使用索引
  • 采用Profiling

常用工具

mongosniff

此工具可以从底层监控到底有哪些命令发送给了MongoDB 去执行,从中就可以进行分析:以root 身份执行:
$./mongosniff –source NET lo
然后其会监控位到本地以localhost 监听默认27017 端口的MongoDB 的所有包请求。

mongostat

此工具可以快速的查看某组运行中的MongoDB 实例的统计信息 字段说明:
insert: 每秒插入量
query: 每秒查询量
update: 每秒更新量
delete: 每秒删除量
locked: 锁定量
qr | qw: 客户端查询排队长度(读|写)
ar | aw: 活跃客户端量(读|写)
conn: 连接数
time: 当前时间
它每秒钟刷新一次状态值,提供良好的可读性,通过这些参数可以观察到一个整体的性能情况。

db.stats

db.stats 查看数据库状态信息。

{    "db" : "test",    "collections" : 8,    "objects" : 31019,    "avgObjSize" : 1037.2548438054096,    "dataSize" : 32174608,    "storageSize" : 100569088,    "numExtents" : 28,    "indexes" : 9,    "indexSize" : 1095584,    "fileSize" : 201326592,    "nsSizeMB" : 16,    "dataFileVersion" : {        "major" : 4,        "minor" : 5    },    "extentFreeList" : {        "num" : 0,        "totalSize" : 0    },    "ok" : 1}

db.serverStatus

查看实例运行状态。

参考

  • MySQL:索引工作原理
  • MySQL索引背后的数据结构及算法原理
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小孩牙齿被虫子吃了个洞怎么办 一岁宝宝贫血值是84怎么办 荒岛求生手机版被困在石室里怎么办 工伤认定期间被厂里辞退工资怎么办 怀孕50天看恐怖片肚子阴痛怎么办 欧卡二进游戏就卡画面了怎么办 魅族手机的微信图标找不到了怎么办 金立手机:微信图标找不到怎么办? 鞋厂装跟机老是卡钉怎么办 苹果手机摔了一下开不了机怎么办 百度网盘解析的种子保存不了怎么办 下载了种子百度网盘解析不了怎么办 正畸复诊后吃饭一直会磨嘴怎么办 遇到儿子说话对母亲不满母亲怎么办 冰箱旧了怎么办教你创新冰箱翻新法 微信陌生人加好友发红包怎么办 微信红包发了对方收不到怎么办 发红包是微信密码不知道了该怎么办 微信上红包密码不知道密码怎么办 本人不知道微信自动发红包怎么办 微信钱包里的钱没了怎么办 微信聊天删除了红包没领怎么办 微信红包未领取删掉了怎么办 微信红包没领取删掉了怎么办 微信红包没领取就删除好友了怎么办 老公一个人出去玩不愿带老婆怎么办 干了一年也攒不下钱怎么办 住院出院后请领导同事吃饭怎么办 有同事请吃饭答应了又不想去怎么办 同事请吃饭发红包不收怎么办 同事要走了请吃饭我不想去怎么办 请领导吃饭他说今晚有事我该怎么办 两个月的狗狗不吃狗粮怎么办 挖机驾驶室的小镙杆总是掉该怎么办 开挖机出了事故没有证怎么办 发现小孩有早恋现象做家长该怎么办 马上中考了初三孩子不上学怎么办 初三孩子老说自己难受不上学怎么办 幼儿园安全教案迷路了怎么办及反思 老婆发现我出轨后离家出走了怎么办 把丝袜放进马桶水箱堵了怎么办