面试题答案
一键面试单字段索引
- 插入操作:
- 影响:插入性能会略有下降。因为每次插入新文档时,MongoDB需要同时更新索引结构。例如,假设我们有一个集合
users
,为name
字段创建单字段索引。 - 示例:
db.users.createIndex({name: 1}); // 插入操作 db.users.insertOne({name: "John", age: 30}); // 由于有索引,插入时不仅要插入文档,还要更新索引,相比无索引插入会稍慢
- 影响:插入性能会略有下降。因为每次插入新文档时,MongoDB需要同时更新索引结构。例如,假设我们有一个集合
- 删除操作:
- 影响:删除性能也会受一定影响。删除文档时,不仅要从集合中移除文档,还要从索引中移除相关的索引项。比如从
users
集合删除name
为“John”的文档。 - 示例:
db.users.deleteOne({name: "John"}); // 此时不仅要从集合中删除文档,还要从`name`字段的索引中移除相关项,导致删除操作比无索引时稍慢
- 影响:删除性能也会受一定影响。删除文档时,不仅要从集合中移除文档,还要从索引中移除相关的索引项。比如从
- 更新操作:
- 影响:如果更新涉及索引字段,更新性能会下降。因为不仅要更新文档中的字段值,还要更新索引中对应的值。例如更新
users
集合中name
为“John”的用户的年龄。 - 示例:
db.users.updateOne({name: "John"}, {$set: {age: 31}}); // 由于更新不涉及索引字段`name`,性能影响相对较小;但如果更新`name`字段,就需要同时更新索引,性能下降更明显
- 影响:如果更新涉及索引字段,更新性能会下降。因为不仅要更新文档中的字段值,还要更新索引中对应的值。例如更新
- 查询操作:
- 影响:显著提升查询性能。如果查询条件包含索引字段,MongoDB可以利用索引快速定位文档。例如查询
name
为“John”的用户。 - 示例:
db.users.find({name: "John"}); // 由于有`name`字段的索引,查询速度会比无索引时快很多
- 影响:显著提升查询性能。如果查询条件包含索引字段,MongoDB可以利用索引快速定位文档。例如查询
复合索引
- 插入操作:
- 影响:插入性能下降更明显。因为复合索引包含多个字段,插入文档时需要更新更为复杂的索引结构。例如在
users
集合为name
和age
字段创建复合索引。 - 示例:
db.users.createIndex({name: 1, age: 1}); // 插入文档 db.users.insertOne({name: "Jane", age: 25}); // 插入时要更新包含`name`和`age`两个字段的复合索引,性能下降比单字段索引更显著
- 影响:插入性能下降更明显。因为复合索引包含多个字段,插入文档时需要更新更为复杂的索引结构。例如在
- 删除操作:
- 影响:删除性能下降更严重。删除文档时,要从包含多个字段的复合索引中移除相关项。比如删除
name
为“Jane”且age
为25的文档。 - 示例:
db.users.deleteOne({name: "Jane", age: 25}); // 要从复合索引中移除相关项,相比单字段索引删除操作,耗时会更长
- 影响:删除性能下降更严重。删除文档时,要从包含多个字段的复合索引中移除相关项。比如删除
- 更新操作:
- 影响:若更新涉及复合索引中的字段,性能下降显著。因为要同时更新多个字段在索引中的值。例如更新
name
为“Jane”且age
为25的用户的年龄。 - 示例:
db.users.updateOne({name: "Jane", age: 25}, {$set: {age: 26}}); // 由于更新涉及复合索引中的`age`字段,不仅要更新文档,还要更新复合索引中`age`字段相关的值,性能影响较大
- 影响:若更新涉及复合索引中的字段,性能下降显著。因为要同时更新多个字段在索引中的值。例如更新
- 查询操作:
- 影响:对于符合复合索引顺序的查询条件,查询性能提升极大。例如查询
name
为“Jane”且age
为25的用户。 - 示例:
db.users.find({name: "Jane", age: 25}); // 由于查询条件与复合索引`{name: 1, age: 1}`顺序匹配,查询性能会得到显著提升
- 影响:对于符合复合索引顺序的查询条件,查询性能提升极大。例如查询
总体而言,索引对查询操作有积极的性能提升作用,但对插入、删除和更新操作会带来一定的性能损耗,在设计索引时需要综合考虑应用场景的读写需求。