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
只是为了提醒,类似于unique
、sparse
等等。
但它也有其他含义。仅仅因为 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,尽管被创建为这样,但在过去的创建过程中仍然存在,所以我不确定我是否得到第一行。 我只是想说,sparse
、unique
只是标识符,如果您调用 db.collection.getIndexes()
,您可能会看到。 F.e.如果您将索引创建为sparse
,那么您将在其描述中看到sparse : true
。 background
、dropDups
和其他参数也有相同的行为。换句话说,在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 每次都要创建索引吗的主要内容,如果未能解决你的问题,请参考以下文章
我们可以在 Switch 上创建索引吗?MongoDB 中的案例
Spring Data Mongo @Indexed 多次创建索引