在数据量超大的情形下,任何数据库系统在创建索引时都是一个耗时的大工程。MongoDB也不例外。因此,MongoDB索引的创建有两个选择,一个是前台方式,一个是后台方式。那这两种方式有什么差异呢,在创建索引是是否能观察到索引完成的进度呢。本文将是基于此的描述,同时也描述了索引创建相关的注意事项。

一、索引创建方式


  1. 前台方式

  2. 缺省情况下,当为一个集合创建索引时,这个操作将阻塞其他的所有操作。即该集合上的无法正常读写,直到索引创建完毕

  3. 任意基于所有数据库申请读或写锁都将等待直到前台完成索引创建操作

  4. 后台方式

  5. 将索引创建置于到后台,适用于那些需要长时间创建索引的情形

  6. 这样子在创建索引期间,MongoDB依旧可以正常的为提供读写操作服务

  7. 等同于关系型数据库在创建索引的时候指定online,而MongoDB则是指定background

  8. 其目的都是相同的,即在索引创建期间,尽可能的以一种占用较少的资源占用方式来实现,同时又可以提供读写服务

  9. 后台创建方式的代价:索引创建时间变长

  10. 后台创建索引的示例

  11. db.people.createIndex( { zipcode: 1}, {background: true} )

  12. db.people.createIndex( { city: 1}, {background: true, sparse: true } )

  13. 缺省情况下background选项的值为false

二、索引创建期间注意事项


  1. 如前所述,基于后台创建索引时,其他的数据库操作能被完成。但是对于mongo shell会话或者你正在创建索引的这个连接

  2. 将不可用,直到所有创建完毕。如果需要做一些其它的操作。则需要再建立其它的连接。

  3. 在索引创建期间,即使完成了部分索引的创建,索引依旧不可用,但是一旦创建完成即可使用。

  4. 基于后台创建索引期间不能完成涉及该集合的相关管理操作

  5. repairDatabase

  6. db.collection.drop()

  7. compact

  8. 意外中断索引创建

  9. 如果在后台创建索引期间,mongod实例异常终止,当mongod实例重新启动后,未完成的索引创建将作为前台进程来执行

  10. 如果索引创建失败,比如由于重复的键等,mongod将提示错误并退出

  11. 在一个索引创建失败后启动mongod,可以使用storage.indexBuildRetry or --noIndexBuildRetry跳过索引创建来启动

三、索引创建期间性能


  1. 后台创建索引比前台慢,如果索引大于实际可用内存,则需要更长的时间来完成索引创建

  2. 所有涉及到该集合的相关操作在后台期间其执行效能会下降,应在合理的维护空挡期完成索引的创建

四、索引的命名规则


  1. 缺省情况下,索引名以键名加上其创建顺序(1或者-1)组合而成。

  2. db.products.createIndex( { item: 1, quantity: -1 } )

  3. 比如上面的索引创建后,其索引名为item_1_quantity_-1

  4. 可以指定自定义的索引名称

  5. db.products.createIndex( { item: 1, quantity: -1 } , { name: "inventory_idx" } )

  6. 如上方式,我们指定了了索引名称为inventory_idx

五、查看索引创建进度


  1. 可使用 db.currentOp() 命令观察索引创建的完成进度

  2. > db.currentOp(

  3. {

  4. $or: [

  5. { op: "command", "query.createIndexes": { $exists: true } },

  6. { op: "insert", ns: /\.system\.indexes\b/ }

  7. ]

  8. }

  9. )

  10. //下面通过一个索引创建示例来查看索引完成进度

  11. //首选创建一个500w文档的集合

  12. > db.version() // Author : Leshami

  13. 3.2.10 // Blog : http://blog.csdn.net/leshami

  14. > for (var i=1;i<=5000000;i++){

  15. db.inventory.insert({id:i,item:"item"+i,stock:Math.floor(i*Math.random())})

  16. }

  17. WriteResult({ "nInserted" : 1 })

  18. > db.inventory.find().limit(3)

  19. { "_id" : ObjectId("581bfc674b0d633653f4427e"), "id" : 1, "item" : "item1", "stock" : 0 }

  20. { "_id" : ObjectId("581bfc674b0d633653f4427f"), "id" : 2, "item" : "item2", "stock" : 0 }

  21. { "_id" : ObjectId("581bfc674b0d633653f44280"), "id" : 3, "item" : "item3", "stock" : 1 }

  22. > db.inventory.find().count()

  23. 5000000

  24. //下面开始创建索引

  25. > db.inventory.createIndex({item:1,unique:true})

  26. //使用下面的命令查看索引完成进度

  27. > db.currentOp(

  28. {

  29. $or: [

  30. { op: "command", "query.createIndexes": { $exists: true } },

  31. { op: "insert", ns: /\.system\.indexes\b/ }

  32. ]

  33. }

  34. )

  35. //结果如下

  36. {

  37. "inprog" : [

  38. {

  39. "desc" : "conn1", //连接描述

  40. "threadId" : "139911670933248", //线程id

  41. "connectionId" : 1,

  42. "client" : "127.0.0.1:37524", //ip及端口

  43. "active" : true, //活动状态

  44. "opid" : 5014925,

  45. "secs_running" : 21, //已执行的时间

  46. "microsecs_running" : NumberLong(21800738),

  47. "op" : "command",

  48. "ns" : "test.$cmd",

  49. "query" : {

  50. "createIndexes" : "inventory", //这里描述了基于inventory正在创建索引

  51. "indexes" : [

  52. {

  53. "ns" : "test.inventory",

  54. "key" : {

  55. "item" : 1,

  56. "unique" : true

  57. },

  58. "name" : "item_1_unique_true"

  59. }

  60. ]

  61. },

  62. "msg" : "Index Build Index Build: 3103284/5000000 62%", //这里是完成的百分比

  63. "progress" : {

  64. "done" : 3103722,

  65. "total" : 5000000

  66. },

  67. "numYields" : 0,

  68. "locks" : { //当前持有的锁

  69. "Global" : "w",

  70. "Database" : "W",

  71. "Collection" : "w"

  72. },

  73. "waitingForLock" : false,

  74. "lockStats" : { //锁的状态信息

  75. "Global" : {

  76. "acquireCount" : {

  77. "r" : NumberLong(1),

  78. "w" : NumberLong(1)

  79. }

  80. },

  81. "Database" : {

  82. "acquireCount" : {

  83. "W" : NumberLong(1)

  84. }

  85. },

  86. "Collection" : {

  87. "acquireCount" : {

  88. "w" : NumberLong(1)

  89. }

  90. }

  91. }

  92. }

  93. ],

  94. "ok" : 1

  95. }

  96. //基于后台方式创建索引

  97. > db.inventory.createIndex({item:1,unique:true},{background: true})

六、终止索引的创建

    db.killOp() 

 

mongo之 前后台创建索引 --noIndexBuildRetry的更多相关文章

  1. linux环境给mongodb创建索引

    首先我们来了解索引,如果有基础的可以直接看最后面的操作. 可参照 DoNotStop 的CSDN 博客 ,全文地址请点击: https://blog.csdn.net/u013725455/artic ...

  2. Elasticsearch之curl创建索引库

    关于curl的介绍,请移步 Elasticsearch学习概念之curl 启动es,请移步 Elasticsearch的前后台运行与停止(tar包方式) Elasticsearch的前后台运行与停止( ...

  3. MongoDB排序时内存大小限制和创建索引的注意事项!

    线上服务的MongoDB中有一个很大的表,我查询时使用了sort()根据某个字段进行排序,结果报了下面这个错误: [Error] Executor error during find command ...

  4. SQL语句-创建索引

    语法:CREATE [索引类型] INDEX 索引名称ON 表名(列名)WITH FILLFACTOR = 填充因子值0~100 GO USE 库名GO IF EXISTS (SELECT * FRO ...

  5. *使用while循环遍历数组创建索引和自增索引值

    package com.chongrui.test;/* *使用while循环遍历数组 *  *  * */public class test {    public static void main ...

  6. 程序员眼中的 SQL Server-执行计划教会我如何创建索引?

    先说点废话 以前有 DBA 在身边的时候,从来不曾考虑过数据库性能的问题,但是,当一个应用程序从头到脚都由自己完成,而且数据库面对的是接近百万的数据,看着一个页面加载速度像乌龟一样,自己心里真是有种挫 ...

  7. SQL Server创建索引(转)

    什么是索引 拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K .为了加快查找的速度,汉语字(词)典一般都有按拼音. ...

  8. hive创建索引

    索引是hive0.7之后才有的功能,创建索引需要评估其合理性,因为创建索引也是要磁盘空间,维护起来也是需要代价的 创建索引 hive> create index [index_studentid ...

  9. MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划

    这篇文章主要介绍了MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划的相关资料,需要的朋友可以参考下 一.索引 MongoDB 提供了多样性的索引支持,索引信息被保存 ...

随机推荐

  1. springboot 打包部署

    springboot内置有tomcat所以我们测试的时候没有加入自己的容器 那么我们的 springboot 怎么发布呢? 1.打成 jar 2.打成 war 这种方式我就不说了,网上有教程,我觉得j ...

  2. redis 五大数据类型之hash篇

    1.hset/hget/hmset/hmget/hgetall/hdel --hgetall 是以截图中 key-value 分别一一显示出来,k1对应v1 ,k2对应v2 2.hlen 3.hexi ...

  3. SDK Manager的使用

    前言:SDK Manager就是一个Android软件开发工具包管理器,就像一个桥梁,连通本地和服务器,从服务器下载安卓开发所需工具到本地. 1.在android sdk 安装目录下,有一个SDK M ...

  4. TensorFlow随机值:tf.random_normal函数

    tf.random_normal 函数 random_normal( shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=No ...

  5. MAVEN JDK版本配置

    使用maven的时候,默认会使用1.5版本的JDK,并且也是编译成1.5的,我的电脑里面用的JDK是1.7的,1.8也出来了,没理由还用1.5的吧!所以我手动改成了1.7,郁闷的是,每次 maven- ...

  6. python day16--面向对象(01)

    一.概念 类:具有相同属性的一类事物 比如人类是类,人类中的某个人是对象.食物是一类,米饭是一个对象 class Person: '''类体:两部分:变量部分,方法(函数)部分''' mind = ' ...

  7. HDU 6063 17多校3 RXD and math(暴力打表题)

    Problem Description RXD is a good mathematician.One day he wants to calculate: ∑i=1nkμ2(i)×⌊nki−−−√⌋ ...

  8. Oracle无监听程序

    小编在使用oracle时经常遇到“ 报错“ORA-12541: TNS: 无监听程序”” 多方搜索,找到一个很好的解决方法,给大家分享一下: 1 从开始菜单中打开“Oracle Net Configu ...

  9. 了解数据模型、以及MySQL使用的数据模型

    1.什么是数据模型? 数据模型是数据库系统的核心与基础,是关于数据与数据之间的联系.数据的语义.数据一致性约束的概念性工具的集合. 数据模型的三个组成部分: 数据结构.数据操作.完整性约束. 数据操作 ...

  10. 百练6255-单词反转-2016正式B题

    百练 / 2016计算机学科夏令营上机考试 已经结束 题目 排名 状态 统计 提问   B:单词翻转 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 输入一个 ...