You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When your application starts up, Mongoose automatically calls createIndex for each defined index in your schema...While nice for development, it is recommended this behavior be disabled in production since index creation can cause a significant performance impact.
The ensureIndex() function checks to see if an index with that name already exists, and, if not, does not attempt to create the index. createIndex() bypasses this check.
今天在看 mongoose 的文档的时候,文档上推荐关闭
autoIndex
这个选项,原文如下:这段话引起了我一连串的思考:为什么创建索引会影响性能?“索引”指的到底是什么?关闭了
autoIndex
会有什么影响,关闭之后我又该如何管理索引?带着这一连串的问题,我一头扎进了文档里面……索引到底是什么?
我们都知道创建索引会提升数据库的性能,但"索引"是什么,它是如何被创建的,它为什么能提高性能?这里我会尝试用 JavaScript 里的数组简单模拟一下索引的工作原理。
假设现在我们有一个数组:
如果我们要找到
name
为王五
的数据,我们一般会循环一遍数组:这看起来没什么问题,但如果数组里有一亿条数据呢?每次查询都完整循环一遍数组将耗费大量时间,但如果我们用
name
属性给这个数组建立一个索引,查询数据将非常快:真正建立索引的过程当然更复杂,但这个例子在解释了索引如何加快查询速度时,也暴露出了索引的三个问题:
所以, MongoDB 对索引有一系列限制,例如每个集合最多只能有 64 个索引、组合索引中的字段个数不能超过 31 个等。
autoIndex 到底该不该关闭?
在上一节中,我们解释了为什么创建索引会降低性能,这也是 Mongoose 建议我们在生产环境中关闭
autoIndex
的原因,但对于一个新应用来说,数据库里一开始是没有数据的,所以建立索引并不会花多长时间;另外,前面说过ensureIndex
会判断索引是否存在来决定要不要建立索引,如果索引没有变化的话,调用ensureIndex
也不会影响多少性能。这么说来,
autoIndex
开着也没问题咯?其实这里面有一个坑————mongoose 中调用的ensureIndex
方法只会创建索引,不会自动删除索引。举个例子,你有一个没有关闭
autoIndex
的应用,某一天你修改了代码中的 Schema,将一个原本是索引的属性name
改成了非索引属性,将另一个属性age
改为了索引属性,那么当应用再次上线,mongoose 自动调用了ensureIndex
方法后,接下来会发生两件事情:name
的索引并没有删除age
创建索引,但因为已经有了name
索引,在此基础上创建新索引可能会让创建时间更长(未经考证)让
autoIndex
保持开启可能会让你意识不到修改了 Schema 可能会导致很长一段时间内性能受到影响,另外,即使索引没有修改过,调用ensureIndex
比不调用它或多或少还是会让性能受到一点影响。所以,推荐的做法是在生产环境关闭
autoIndex
,用 mongo Shell 手动管理索引;又或者在更改了索引之后,在代码中调用dropIndex
和ensureIndex
,并确保这两个方法在修改了 Schema 后,应用多次重启都只会运行一次,直到下次修改索引——当然,索引最好是越少修改越好,随着数据量越来越大,建立索引的时间只会越来越长。我的选择
作为懒癌患者,我决定在生产环境开启
autoIndex
,然后确保修改 Schema 后删除不再需要的索引 😂关于文章开头 Mongoose 文档中的那段话
这段说明似乎有误,因为源码里用的是 ensureIndex 而不是 createIndex,相关代码(按代码执行顺序排序):
另外,Mongoose 的文档对
ensureIndex
的描述是:但 MongoDB 对
ensureIndex
的说明是:然后 MongoDB 的文档对
createIndex
的描述是:读到这些我很是疑惑,MongoDB 中的
ensureIndex
与createIndex
似乎并没有区别,另外ensureIndex
并不是 Mongoose 中说的“不会尝试创建不存在的索引”……The text was updated successfully, but these errors were encountered: