Skip to content

MongoDB 索引

索引是 MongoDB 中用于提高查询性能的重要工具。它们类似于书籍的目录,允许 MongoDB 快速定位和访问数据,而无需扫描整个集合。

基本概念

索引的工作原理

索引在 MongoDB 中以 B 树结构存储,这使得查询操作可以快速定位到所需的数据。当我们在集合上创建索引时,MongoDB 会创建一个单独的数据结构,该结构包含索引字段的值和指向集合中对应文档的指针。

索引的类型

  1. 单字段索引:在单个字段上创建的索引
  2. 复合索引:在多个字段上创建的索引
  3. 多键索引:在数组字段上创建的索引
  4. 地理位置索引:用于地理空间查询的索引
  5. 文本索引:用于文本搜索的索引
  6. 哈希索引:用于哈希查询的索引

创建索引

创建单字段索引

javascript
// 为 name 字段创建升序索引
db.users.createIndex({ name: 1 })

// 为 age 字段创建降序索引
db.users.createIndex({ age: -1 })

创建复合索引

javascript
// 为 name 和 age 字段创建复合索引
db.users.createIndex({ name: 1, age: -1 })

创建唯一索引

javascript
// 为 email 字段创建唯一索引
db.users.createIndex({ email: 1 }, { unique: true })

后台创建索引

在默认情况下,创建索引操作会阻塞其他操作。我们可以使用 background 选项在后台创建索引。

javascript
// 在后台为 name 字段创建索引
db.users.createIndex({ name: 1 }, { background: true })

查看索引

查看集合的所有索引

javascript
db.users.getIndexes()

查看索引的大小

javascript
db.users.stats()

删除索引

删除单个索引

javascript
// 删除 name 字段上的索引
db.users.dropIndex({ name: 1 })

// 或者使用索引名称删除
db.users.dropIndex("name_1")

删除所有索引

javascript
db.users.dropIndexes()

索引的使用

查询时使用索引

MongoDB 会自动选择合适的索引来优化查询。我们可以使用 explain() 方法来验证查询是否使用了索引。

javascript
// 查询 age 大于 30 的文档,并验证是否使用了索引
db.users.find({ age: { $gt: 30 } }).explain()

强制使用特定索引

我们可以使用 hint() 方法强制查询使用特定的索引。

javascript
// 强制查询使用 age_1 索引
db.users.find({ age: { $gt: 30 } }).hint("age_1")

索引的优化

索引的选择性

索引的选择性是指索引中不同值的数量与集合中文档数量的比值。选择性越高的索引,查询性能越好。

覆盖查询

覆盖查询是指查询的字段和排序的字段都包含在索引中,从而避免了对集合的扫描。

javascript
// 查询 name 和 age 字段,并按 name 字段排序
// 如果有复合索引 { name: 1, age: 1 },则会使用覆盖查询
db.users.find({ name: /^J/ }, { name: 1, age: 1 }).sort({ name: 1 })

避免过度索引

虽然索引可以提高查询性能,但过多的索引会导致写入操作变慢。我们应该根据实际需要创建适当数量的索引。

常见问题

索引的创建时间

索引的创建时间取决于集合的大小和索引字段的类型。在大型集合上创建索引可能需要较长的时间。

索引的存储

索引会占用额外的存储空间。我们应该定期检查索引的大小,并根据需要优化索引。

索引的维护

当集合中的数据发生变化时,索引会自动更新。这会导致写入操作变慢,特别是在大型集合上。

总结

索引是 MongoDB 中提高查询性能的重要工具。我们可以根据需要创建不同类型的索引,以优化查询操作。同时,我们也需要注意索引的维护和优化,以确保查询性能的持续提升。