139

根据和/的Mongoose文档MongooseJSMongoDBNode.js

当您的应用程序启动时,Mongoose 会自动调用ensureIndex您架构中定义的每个索引。虽然很适合开发,但建议在生产中禁用此行为,因为创建索引会导致显着的性能影响。autoIndex通过将架构的选项设置为 false 来禁用该行为。

这似乎指示在部署之前从 mongoose 中删除自动索引,以优化 Mongoose 从指示 Mongo 在应用程序启动时遍历所有索引,这似乎是有道理的。

在生产代码中处理索引的正确方法是什么?也许外部脚本应该生成索引?或者,ensureIndex如果单个应用程序是集合的唯一读取器/写入器,则可能是不必要的,因为每次发生数据库写入时它都会继续索引?

编辑:作为补充,MongoDB 为如何进行索引提供了很好的文档但没有提供明确索引指令的原因时间。在我看来,索引应该由编写器应用程序自动在具有现有索引的集合上保持最新,这实际上更像是一次性的事情(在应用新索引时完成),在这种情况下,猫鼬应该是no-op 下服务器正常重启。ensureIndexautoIndex

4

3 回答 3

151

我一直不明白为什么 Mongoose 文档如此广泛地建议autoIndex在生产中禁用。添加索引后,后续ensureIndex调用将简单地看到索引已经存在,然后返回。所以它只会在你第一次创建索引时对性能产生影响,那时集合通常是空的,所以无论如何创建索引都会很快。

我的建议是保持autoIndex启用状态,除非您遇到给您带来麻烦的特定情况;例如,如果您想向拥有数百万个文档的现有集合添加新索引,并且您希望更好地控制它的创建时间。

于 2013-01-15T21:05:15.023 回答
43

虽然我同意接受的答案,但值得注意的是,根据MongoDB 手册,这不是在生产服务器上添加索引的推荐方法:

如果您的应用程序包含 ensureIndex() 操作,并且不存在其他操作问题的索引,则构建索引可能会对数据库的性能产生严重影响。

为避免性能问题,请确保您的应用程序在启动时使用 getIndexes() 方法或驱动程序的等效方法检查索引,并在不存在正确索引时终止。在指定的维护窗口期间,始终使用单独的应用程序代码在生产实例中构建索引。

当然,这实际上取决于您的应用程序的结构和部署方式。例如,如果您正在部署到 Heroku,并且您没有使用 Heroku 的预启动功能,那么您的应用程序很可能在启动期间根本没有服务请求,因此此时创建索引可能是安全的。

除此之外,从接受的答案:

所以它只会在你第一次创建索引时对性能产生影响,那时集合通常是空的,所以无论如何创建索引都会很快。

如果您第一次就成功地确定了您的数据模型和查询,这很好,而且通常是这样。但是,如果您要向应用程序添加新功能,并在没有索引的属性上使用新的数据库查询,您通常会发现自己将索引添加到包含许多现有文档的集合中。

这是您需要小心添加索引并仔细考虑这样做的性能影响的时候。例如,您可以在后台创建索引

db.ensureIndex({ name: 1 }, { background: true });
于 2015-06-03T09:51:29.047 回答
2

使用此块代码来处理生产模式:

const autoIndex = process.env.NODE_ENV !== 'production';
mongoose.connect('mongodb://localhost/collection', { autoIndex });
于 2019-05-07T09:04:22.957 回答