翻译或纠错本页面

Index Build

默认情况下,创建索引会阻塞数据库中所有其他操作。当在一个集合上创建索引时,存储了这个集合的数据库变成不可读不可写的状态知道索引建立完毕。任何需要所有数据库中读或者写锁的操作(例如 listDatabases )将会等待,直到后台索引创建完成。

后台创建

对于可能需要长时间运行的索引创建操作,可以考虑 background 选项,这样MongoDB数据库在索引创建期间仍然是可用的。例如,在 people 集合的 zipcode 键上创建一个索引,这个过程在后台运行,可以使用如下方式:

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

默认地,MongoDB索引创建的 backgroundfalse

您可以将background选项和其他选项组合在一起,如下:

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

特性

到了MongoDB版本2.4及之后,一个 mongod 实例可以在后台并发创建多个索引。

在 2.4 版更改: 在2.4以前,一个 mongod 实例同一时刻只能在后台为每个数据库创建一个索引。

在后台创建索引这样其他的数据库操作可以被执行。但是,执行这个索引创建操作的 mongo shell的会话或者连接 将会 阻塞直到索引创建完毕。如果希望继续对这个数据库操作,请重新开启一个连接或者 mongo shell实例。

查询将不会使用部分建立的索引:索引只有在建立完毕之后才是可用的。

注解

如果MongoDB在后台创建一个索引,您不能执行其他会涉及到该集合的管理操作,包括 repairDatabase 命令,删除集合(例如 db.collection.drop() ),和 compact 命令。当后台创建索引时,这些操作会返回一个错误。

性能

后台索引创建操作使用的是一种增量的方式,这会比普通的 “前台” 创建过程慢。如果索引大于现有的内存,那么这个增量处理过程将会比前台创建过程 久得多

如果您的应用中包含 ensureIndex() 操作,且出于其他操作上的考虑这个索引 存在,那么建立一个索引可能会对数据库的性能有严重影响。

为了避免性能问题,请确保您的应用在启动时就使用 getIndexes() 方法或者其他 equivalent method for your driver 检查索引是否存在,如果不存在请退出应用。或者在生产实例上使用不同的应用代码在指定的维护时间窗口期间创建索引。

Interrupted Index Builds

If a background index build is in progress when the mongod process terminates, when the instance restarts the index build will restart as foreground index build. If the index build encounters any errors, such as a duplicate key error, the mongod will exit with an error.

To start the mongod after a failed index build, use the storage.indexBuildRetry or --noIndexBuildRetry to skip the index build on start up.

在从节点上(Secondaries)建立索引

在 2.6 版更改: 从节点成员限制夜可以在后台创建索引了。之前的版本,所有在从节点上建立的索引都必须是在前台建立。

primary 完成索引创建后, replica set secondaries 开始在后台创建索引操作。如果MongoDB在主节点上后台创建索引,那么之后从节点也会在后台创建索引。

在从节点上建立大索引的最好方式是以 standalone 模式重启一个从节点并建立索引。 索引建立完成后,重启为复制集成员,这样它可以同步跟上其他成员,然后以同样方式在下一个从节点上建立索引。当所有从节点都有新索引了,让主节点下台并作为单机实例重启,然后创建索引。

在从节点上建立索引的时间应该小于 oplog 时间窗口,这样从节点可以同步跟上主节点。

当在 “recovering” 模式的从节点上索引时,索引创建过程总是在前台执行,这样它们可以尽可能快的同步跟上。

参见 在复制集上创建索引 对从节点上创建索引过程有一个完整了解。

索引名字

一个索引的默认名字是每个被索引键和键的方向如1,-1的拼接。

例子

Issue the following command to create an index on item and quantity:

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

这个索引的名字是: item_1_quantity_-1

您可以为索引指定一个名字,代替默认名字。

例子

Issue the following command to create an index on item and quantity and specify inventory as the index name:

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

最终这个索引的名字会是 inventory

您可以使用 getIndexes() 方法来查看一个索引的名字。

View Index Build Operations

To see the status of an index build operation, you can use the db.currentOp() method in the mongo shell. To filter the current operations for index creation operations, see Active Indexing Operations for an example.

The msg field will include the percent of the build that is complete.

Terminate Index Build Operation

To terminate an ongoing index build, use the db.killOp() method in the mongo shell. For index builds, the effects of db.killOp() may not be immediate and may occur well after much of the index build operation has completed.

You cannot terminate a replicated index build on secondary members of a replica set. To minimize the impact of building an index on replica sets, see 在复制集上创建索引.

在 2.4 版更改: Before MongoDB 2.4, you could only terminate background index builds. After 2.4, you can terminate both background index builds and foreground index builds.