Mongodb:何时调用ensureIndex?

时间:2011-08-09 18:12:23

标签: mongodb indexing

我什么时候应该打电话给ensureIndex?插入单个记录之前,插入单个记录之后,还是在调用find()?

之前

此致

约翰尼

7 个答案:

答案 0 :(得分:18)

我的评论似乎有点被误解了,所以我会澄清一下。只要在第一次调用find()之前在某个时刻调用,当你调用它时,它并不重要。换句话说,当你创建它时,它并不重要索引,只要它在你预期使用它之前就已存在。

我见过的一个常见模式是ensureIndexfind()调用同时(并在同一位置)编码。 ensureIndex将检查索引是否存在,如果不存在则创建它。在调用find()之前调用ensureindex毫无疑问会有一些开销(尽管很小),所以最好不要这样做。

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

答案 1 :(得分:15)

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

答案 2 :(得分:3)

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

答案 3 :(得分:2)

你只需要这样做一次。 例如:

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

答案 4 :(得分:1)

如果您事先添加索引,则每次插入/更新/删除调用也必须修改每个索引。因此,从优化角度来看,您可能希望在发出查询之前尽可能长时间地将其关闭。但是,从功能的角度来看,这并不重要。

答案 5 :(得分:1)

我通常将我的ensureIndex()调用放在init块中,用于管理与MongoDB通信的应用程序部分。另外,我将这些ensureIndex()调用包含在检查中是否存在我知道应用程序必须存在的集合才能运行;这样,ensureIndex()调用只会在第一次针对特定MongoDB实例运行应用程序时调用一次。

我在其他地方读过一条反对在应用程序代码中调用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());
    // ...
}

答案 6 :(得分:1)

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

构建索引的模式(前景与后台)增加了额外的复杂性。前台模式在构建索引时锁定完整的数据库,而后台模式允许您查询数据库。然而,索引构建的背景模式需要额外的时间。

因此,您必须确保已成功创建索引。您可以使用db.currentOp()在仍在创建索引时检查ensureIndexes()的进度。