本文内容源自Kyle Banker 的MongoDB In Action一书。主要描述了MongoDB索引相关的一些基础知识和使用技巧。

  索引类型

  虽然MongoDB的索引在存储结构上都是一样的,但是根据不同的应用层需求,还是分成了唯一索引(unique)、稀疏索引(sparse)、多值索引(multikey)等几种类型。

  1.唯一索引

  唯一索引在创建时加上unique:true 的选项即可,创建命令如下:

  db.users.ensureIndex({username: 1}, {unique: true})
  上面的唯一索引创建后,如果insert一条username已经存在的数据,则会报如下的错误:

  E11000 duplicate key error index: gardening.users.$username_1 dup key: { : "kbanker" }
  如果你在一个已有数据的collection上创建唯一索引,若唯一索引对应的字段原来就有重复的数据项,那么创建会失败,我们需要加上一个dropDups的选项来强制将重复的项删除掉,命令如下例:

  db.users.ensureIndex({username: 1}, {unique: true, dropDups: true})
  2.松散索引

  如果你的数据中一些行中没有某个字段或字段值为null,那么如果在这个字段上建立普通索引,那么无此字段或值null的行也会参与到索引结构中,占用相应的空间。如果我们不希望这些值为空的行参与到我们的索引中,这时候可以采用松散索引,松散索引只会让指定字段不为空的行参与到索引创建中来。创建一个松散索引可以用下面的命令:

  db.reviews.ensureIndex({user_id: 1}, {sparse: true})
  3.多值索引

  MongoDB可以对一个array类型创建索引,比如像下面的结构,MongoDB可以在tags字段上创建索引:

  { name: "Wheelbarrow",

  tags: ["tools", "gardening", "soil"]

  }
  在生成索引时,会为tags中的三个值分别生成三个索引元素,索引中tools,gardening,soil三个值都会指向这同一行数据。相当于分裂成了三个独立的索引项。

  索引管理

  1.索引的创建和删除

  创建和删除索引的方法有很多种,下面两个是比较原始的方法,通过对system.indexes这个collection进行相应的写操作来完成索引的创建:

  spec = {ns: "green.users", key: {‘addresses.zip’: 1}, name: ‘zip’}

  db.system.indexes.insert(spec, true)
  上面命令往system.indexes中写入一条记录来创建索引,这条记录包含了要在上面创建索引的collection的名字空间,索引的信息,以及索引的名称。

  创建完成后,我们可以通过下面命令找到我们创建的索引:

  db.system.indexes.find()

  { "_id" : ObjectId("4d2205c4051f853d46447e95"), "ns" : "green.users",

  "key" : { "addresses.zip" : 1 }, "name" : "zip", "v" : 0 }
  要删除一个已创建的索引,我们可以使用下面的命令来实现:

  use green

  db.runCommand({deleteIndexes: "users", index: "zip"})
  2.创建索引命令

  实际上创建索引还有更方便的命令,那就是ensureIndex,比如我们创建一个open和close两个字段的联合索引,就可以用下面的命令:

  db.values.ensureIndex({open: 1, close: 1})
  这个命令会触发索引创建的两个过程,一个是将相应的字段排序,因为索引是按B+树来组织的,要构建树,将数据进行排序后能够提高插入B+树的效率(第二个过程的效率),在日志中,你能看到和下面类似的输出:

  Tue Jan 4 09:58:17 [conn1] building new index on { open: 1.0, close: 1.0 } for stocks.values

  1000000/4308303 23%

  2000000/4308303 46%

  3000000/4308303 69%

  4000000/4308303 92%

  Tue Jan 4 09:59:13 [conn1] external sort used : 5 files in 55 secs
  第二个过程是将排序好的数据插入到索引结构中,构成可用的索引:

  1200300/4308303 27%

  2227900/4308303 51%

  2837100/4308303 65%

  3278100/4308303 76%

  3783300/4308303 87%

  4075500/4308303 94%

  Tue Jan 4 10:00:16 [conn1] done building bottom layer, going to commit

  Tue Jan 4 10:00:16 [conn1] done for 4308303 records 118.942secs

  Tue Jan 4 10:00:16 [conn1] insert stocks.system.indexes 118942ms
  除了日志中的输出外,你还可以通过在终端执行currentOp命令来获取当前操作线程的相关信息,如下例:

  > db.currentOp()

  {

  "inprog" : [

  {

  "opid" : 58,

  "active" : true,

  "lockType" : "write",

  "waitingForLock" : false,

  "secs_running" : 55,

  "op" : "insert",

  "ns" : "stocks.system.indexes",

  "query" : {

  },

  "client" : "127.0.0.1:53421",

  "desc" : "conn",

  "msg" : "index: (1/3) external sort 3999999/4308303 92%"

  }

  ]

  }
  最后一部分就是一个索引构建过程,目前正在执行排序过程,执行到92%。

  3.在后台创建索引

  创建索引会对数据库添加写锁,如果数据集比如大,会将线上读写数据库的操作挂起,以等待索引创建结束。这影响了数据库的正常服务,我们可以通过在创建索引时加background:true 的选项,让创建工作在后台执行,这时候创建索引还是需要加写锁,但是这个写锁不会直接独占到索引创建完成,而是会暂停为其它读写操作让路,不至于造成严重的性能影响。具体方法:

  db.values.ensureIndex({open: 1, close: 1}, {background: true})
  4.离线创建索引

  无论如何,索引的创建都会给数据库造成一定的压力,从而影响线上服务。如果希望创建索引的过程完全不影响线上服务,我们可以通过将replica sets中的节点先从集群中剥离,在这个节点上添加相应的索引,等索引添加完毕后再将其添加到replica sets中。这只需要保证一个条件,就是创建索引的时间不能长于oplog能够保存日志的时间,否则创建完后节点再上线发现再也无法追上primary了,这时会进行resync操作。

  索引备份

  我们知道,无论是使用mongodump还是mongoexport命令,都只是对数据进行备份,无法备份索引。我们在恢复的时候,还是需要等待漫长的索引创建过程。所以,如果你希望备份的时候带上索引,那么最好采用备份数据文件的方式。

  索引压缩

  索引在使用一段时间后,经历增删改等操作,会变得比较松散,从而战用不必要的空间,我们可以通过reindex命令,重新组织索引,让索引的空间占用变得更小。

转载于:https://blog.51cto.com/wws5201985/773843

MongoDB数据库索引基础知识与实战技巧相关推荐

  1. [转]SQL Server 索引基础知识(2)----聚集索引,非聚集索引

    SQL Server 索引基础知识(2)----聚集索引,非聚集索引 [来自]http://blog.joycode.com/ghj/archive/2008/01/02/113291.aspx 由于 ...

  2. SQL Server 索引基础知识(8)--- 数据基本格式补充(转自蝈蝈俊.net)

    我在SQL Server 索引基础知识系列中,第一篇就讲了记录数据的基本格式.那里主要讲解的是,数据库的最小读存单元:数据页.一个数据页是8K大小. 对于数据库来说,它不会每次有一个数据页变化后,就存 ...

  3. 数据库索引-基本知识

    为什么80%的码农都做不了架构师?>>>    数据库索引--基本知识 有许多因素会影响数据库性能.最明显的是数据量:您拥有的数据越多,数据库的速度就越慢.虽然有很多方法可以解决性能 ...

  4. 计算机基础三级,三级数据库计算机基础知识

    <三级数据库计算机基础知识>由会员分享,可在线阅读,更多相关<三级数据库计算机基础知识(9页珍藏版)>请在人人文库网上搜索. 1.模拟 三级数据库计算机基础知识(二)一.选择题 ...

  5. 计算机等级考试电子邮件的保存,计算机基础知识电子邮件使用技巧集锦(二)

    计算机基础知识电子邮件使用技巧集锦(二) 分类:计算机等级 | 更新时间:2016-07-08| 来源:转载 11.用ISP邮箱提高发信速度 现在免费电子邮件大都支持SMTP和POP3协议,故在设置服 ...

  6. 数据库:基础知识总结

    目录 一.数据库基础知识 数据库设计三大范式: 数据仓库数据模型: 数据库分类: SQL语言分类: 二.DDL 操作"数据库"的DDL 操作表的DDL 修改表的DDL 三.DML( ...

  7. SQL Server 索引基础知识(1)--- 记录数据的基本格式

    不论是缓存的数据信息,还是物理保存的信息,他们的基本单位都是数据页.所以理解数据页是最最基础的知识点,本篇博客就介绍跟索引有关的数据页的一些基础知识. 数据页的基础知识 SQL Server 中数据存 ...

  8. NoSQL数据库的基础知识

    关系型数据库和NoSQL数据库 什么是NoSQL 大家有没有听说过"NoSQL"呢?近年,这个词极受关注.看到"NoSQL"这个词,大家可能会误以为是" ...

  9. Oracle数据库,基础知识

    1.Oracle的五大约束条件: 1 主键  primary key 2 外键  foreign key, 3 唯一  unique, 4 检测  check 5 非空  not null 实例运用: ...

最新文章

  1. 《网站分析师实战指南》一1.4 进入实战之路
  2. java-数据库连接,分层实现增删改查测试
  3. 明年就翻身系列:AMD 2017统治PC、服务器市场?
  4. 日志和告警数据挖掘经验谈
  5. 为什么我们对90后的迎合难以成功?
  6. python热成像_在python中自动从图像中移除热/死像素
  7. [置顶]团队开发经验:如何带领一个项目团队并做好项目总结
  8. springboot调用so文件
  9. 机器学习算法(十):线性回归之最小二乘法
  10. 【深度学习算法原理】Deep Structured Semantic Models(DSSM)
  11. android 搜狗地图包名,搜狗地图
  12. 压力测试软件 loadr,初学abench压力测试 - 玄大冰 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
  13. 微信支付成功后服务器宕机了,今天微信出现大面积宕机,可能与支付宝有关?...
  14. 使用tarjan算法和fleury算法求解中国邮递员问题
  15. Web技术-1 Web前端总结
  16. Shrinkage: I was in the pool
  17. Linux 内核编程指南
  18. TensorFlow技术主管Peter Wardan:机器学习的未来是小而美
  19. echarts仪表盘式进度条
  20. 数字孪生应用白皮书(2020版)|PDF下载

热门文章

  1. 2017.3.9 对象 函数
  2. 站长们都会,但是都会写错的robots!
  3. 5、kafka的操作
  4. Python学习第三天--数据类型
  5. NetBeans 时事通讯(刊号 # 22 - Aug 18, 2008)
  6. nginx日志分析查询异常请求IP之狙击网络黑客
  7. php获取分辨率赋值,php如何获取客户端分辨率?实例教程
  8. 8 9区别 endnote7_SAT和ACT的区别,你知道吗?
  9. PHP jQuery Ajax 无刷新表单提交实例
  10. nginx功能扩展整理