mongodb 每次都要创建索引吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mongodb 每次都要创建索引吗相关的知识,希望对你有一定的参考价值。

mongodb在前台直接运行建立索引命令的话,将造成整个数据库阻塞,因此索引建议使用 background 的方式建立。但是这也会带来一定的问题,在
2.6 版本之前,在 secondary server 中即使使用 background 方式建立索引,secondary 还是会以
foreground 方式建立索引,它导致 secondary 同样引发数据库阻塞问题。2.6 版本修复了这个 Bug,2.6 版之后使用
background 方式建立索引时,真正转向后台运行了。
为了尽量降低建立索引对 MongoDB Server 的影响,有一种方法是把 MongoDB Server 转换成 standalone 模式后建立。具体做法如下:
1.首先把 secondary server 停止,在取消 --replSet 参数,并且更改 MongoDB port 之后重新启动 MongoDB,这时候 MongoDB 将进入 standalone 模式;
2.在 standalone 模式下运行命令 ensureIndex 建立索引,建议使用 foreground 方式运行;
3.建立索引完毕之后关闭 secondary server 按正常方式启动;
4.根据上述 1~3 的步骤轮流为 secondary 建立索引,最后把 primary server 临时转换为 secondary server,同样按 1~3 的方法建立索引,再把其转换为 primary server。
这种方式还是比较麻烦的,但可以把建立索引操作对 MongoDB 的影响降到最低,在有些情况下还是值得做的。
参考技术A

(一般来说)不需要。

除非:你的MongoDB的数据量很大(比如我遇到的 270万条),且查询速度太慢(要好几秒),此时,才需要建索引,目的是提高查询速度(建索引后,每次查询只要不到0.01秒)

另外:每个Collection,都有个默认的 key是 _id 的index,是MongoDB系统自己建的。你也无法删除,也不需要删除,也无需你手动单独创建该索引。


详见:(百度搜)

【已解决】用mongo的shell给MongoDB创建索引以提高查询速度

Mongodb 后台索引 - 一旦创建它们仍然是后台吗?

【中文标题】Mongodb 后台索引 - 一旦创建它们仍然是后台吗?【英文标题】:Mongodb background indexes - are they still background once created? 【发布时间】:2013-03-12 20:09:10 【问题描述】:

在mongodb中创建索引时,可以指定background: true标志,这使得索引的创建是非阻塞的。这在生产环境中非常有用,因为您不希望在创建一个以前显然不需要的索引时锁定整个数据库(因为您没有它)。

阅读docs,似乎这个标志只决定了索引的创建方式,一旦创建完成,索引的行为就与普通索引完全一样。这就是我想要的——我不希望索引与文档不同步,因为它正在后台更新,尽管我可以想象一个数据库可以做到这一点。

我在这里问是因为getIndexes 命令显示该索引即使在创建后仍标记为background。这只是一个关于它是如何创建的提醒吗?还是background 索引在创建后表现不同?复制可能有些微妙之处?

【问题讨论】:

【参考方案1】:

创建后,它们就像常规索引一样。他们坚持getIndexes只是为了提醒,类似于uniquesparse等等。

但它也有其他含义。仅仅因为 foreground 索引阻塞了所有写入者,在这种情况下,您将无法执行db.testCollection.getIndexes(),直到所有索引都已创建。同时,当您创建background 索引时,您可以调用db.testCollection.getIndexes(),您会看到,该索引似乎已经创建。

但在这种情况下,我们无法确定索引是否已实际创建。在这种情况下,您需要致电db.currentOp(),如果您看到类似


  "inprog": [
    
      "opid": 2001060,
      "active": true,
      "secs_running": 1,
      "op": "insert",
      "ns": "test.system.indexes",
      "insert": 
        "v": 1,
        "key": 
          "a": 1
        ,
        "ns": "test.testCollection",
        "name": "a_1",
        "background": 1
      ,
          ....
      "msg": "bg index build Background Index Build Progress: 368640/1000000 36%",
      "progress": 
        "done": 368640,
        "total": 1000000
      
      ...
    
  ]

那么这意味着,后台索引的创建仍在进行中,并且您可以看到有关该过程的一些信息。

例如,您可能会进行一些粗略的计算: 1000000 中的 368640 需要 1 秒(+1 秒作为可能的偏移量),因此一切都应该需要 3-6 秒(最终需要 4.8 秒)。

显然,如果您看不到正在进行的此类操作,则说明已经创建了索引。

注意:如果你有很多并发操作,那么你可以为db.currentOp()指定searсh参数,f.e.

db.currentOp("insert.background":1)

【讨论】:

hmm unqiue 和spare,尽管被创建为这样,但在过去的创建过程中仍然存在,所以我不确定我是否得到第一行。 我只是想说,sparseunique 只是标识符,如果您调用 db.collection.getIndexes(),您可能会看到。 F.e.如果您将索引创建为sparse,那么您将在其描述中看到sparse : truebackgrounddropDups 和其他参数也有相同的行为。换句话说,在ensureIndex 中作为第二个参数传递的所有内容都会出现在索引的描述中。 我更新了第一段以反映此评论讨论。 请注意,使用 dropDups:true 可能会导致完成百分比计算错误,因为文档总数减少:"msg" : "bg index build Background Index Build Progress: 67364294/27257585 247%" 在 3.0.12 中我使用这个查询来过滤 currentOp:db.currentOp("query.indexes.background":true)【参考方案2】:

有多个索引选项 - 前景(默认)和背景。前台相对较快,它会阻止所有的作者和读者。我们仍然可以访问的其他数据库。这不应该在生产环境中完成。

后台索引创建速度有点慢,而且它们不会阻止读取器和写入器。使用MongoDB 2.4 及更高版本,您甚至可以在同一个数据库上并行创建多个后台索引。

MongoDB 2.6 开始,在主服务器的后台创建索引也会导致在辅助服务器的后台创建索引。当主节点完成构建索引时,从节点将开始创建索引。

还有另一种方法可以在生产系统中非常有效地创建索引。那就是在用于服务大多数查询的不同服务器上创建索引。比如说,在多个数据库服务器协同工作的副本集中,可以取出一个并将请求路由到可用的服务器。前台索引创建可以在单独的服务器上完成。创建成功后,可以带回集群。

【讨论】:

以上是关于mongodb 每次都要创建索引吗的主要内容,如果未能解决你的问题,请参考以下文章

Mongodb 后台索引 - 一旦创建它们仍然是后台吗?

我们可以在 Switch 上创建索引吗?MongoDB 中的案例

Spring Data Mongo @Indexed 多次创建索引

MongoDB Map Reduce:自动创建的索引名称太长,可以自定义吗?

MongoDB-我如何创建索引有什么问题?

索引及集合管理 - MongoDB从入门到删库