Mongodb:何时调用ensureIndex?

什么时候应该打电话ensureIndex? 在插入单个logging之前,插入单个logging之前,或者在调用find()之前?

问候,

约翰尼

看来我的评论已经有点被误解了,所以我会澄清的。 只要你在第一次调用find()之前调用它, 那么调用它并不重要 换句话说,创build索引的时候并不重要,只要它在你想要使用它之前就已经存在了。

我见过很多的常见模式是在find()调用的同时(和在同一个地方)对ensureIndex进行编码。 ensureIndex将检查索引是否存在,如果不存在则创build它。 在调用find()之前调用ensureindex毫无疑问是一些开销(尽pipe很小),所以最好不要这样做。

我在代码中调用ensureIndex来简化部署,并避免单独pipe理数据库和代码库。 易于部署的权衡平衡了后续调用ensureIndex(对于我)的冗余。

我build议在应用程序启动时调用ensureIndex一次。

没关系,但是你只需要做一次。 如果你想批量插入大量的数据到一个空的集合,那么最好在插入之后创build索引,否则它并不重要。

你只需要做一次。 例:

 db.table.insert({foo: 'bar'}); var foo = db.table.findOne({foo: 'bar'}); // => delivered from FS, not RAM db.table.ensureIndex({foo: 1}); var foo = db.table.findOne({foo: 'bar'}); // => delivered from RAM, not FS db.table.insert({foo: 'foo'}); var foo = db.table.findOne({foo: 'foo'}); // => delivered from RAM, not FS 

如果您事先添加索引,则每个插入/更新/删除调用都必须修改每个索引。 所以,从优化的angular度来看,您可能希望在发出查询之前尽可能地延长它。 但从function的angular度来看,这并不重要。

我通常把我的ensureIndex()调用放在init块中,用于pipe理与MongoDB通信的应用程序部分。 另外,我将这些ensureIndex()调用封装在一个检查集合中,以确认应用程序的function是否存在。 这样,只有在第一次运行应用程序时,ensureIndex()调用才会被调用一次。

我在别处读过一个意见,反对在应用程序代码中放入ensureIndex()调用,因为其他开发人员可能会错误地更改它们并更改数据库(索引),但是将其包含在检查收集的存在有助于防止这种情况。

Java MongoDB驱动程序示例:

 DB db = mongo.getDB("databaseName"); Set<String> existingCollectionNames = db.getCollectionNames(); // init collections; ensureIndexes only if creating collection // (let application set up the db if it's not already) DBCollection coll = db.getCollection("collectionName"); if (!existingCollectionNames.contains("collectionName")) { // ensure indexes... coll.ensureIndex(BasicDBObjectBuilder.start().add("date", 1).get()); // ... } 

如果你有一个拥有数百万条logging的集合,并且你正在构build多个复合索引并且自动索引被closures,那么你必须确保在第一次查找查询之前调用ensureIndexes(),可能是在ensureIndexes方法返回之后同步调用。

索引被build立的模式(前景与背景)增加了额外的复杂性。 前台模式locking整个数据库,而它正在build立索引,而背景模式允许你查询数据库。 然而,build立索引的背景模式需要额外的时间。

所以你必须确保索引已经成功创build。 您可以使用db.currentOp()在仍然创build索引的同时检查ensureIndexes()的进度。