MongoDB 的索引是提高查询性能的核心机制,类似于传统关系型数据库的索引。以下是对 MongoDB 索引的详细说明:
一、索引基础
- 索引的作用
加速查询:通过索引快速定位数据,避免全集合扫描(COLLSCAN)。
排序优化:索引可以加速排序操作(如 sort())。
唯一性约束:通过唯一索引(unique: true)确保字段值不重复。
稀疏性控制:稀疏索引(sparse: true)仅对存在该字段的文档创建索引。
- 默认索引
MongoDB 自动为 _id 字段创建唯一索引,不可删除。
二、索引类型
- 单字段索引(Single Field Index)
对单个字段创建索引:
javascript
复制
db.collection.createIndex({ field: 1 }) // 1 表示升序,-1 表示降序
适用于精确匹配或范围查询的字段。
- 复合索引(Compound Index)
对多个字段联合创建索引:
javascript
复制
db.collection.createIndex({ field1: 1, field2: -1 })
字段顺序重要:查询条件中字段的顺序需与索引一致或前缀匹配。
排序优化:索引字段的顺序会影响 sort() 的性能。
- 多键索引(Multikey Index)
自动为数组字段中的每个元素创建索引:
javascript
复制
db.collection.createIndex({ arrayField: 1 })
适用于查询数组中的元素(如 arrayField: value)。
- 文本索引(Text Index)
支持全文搜索:
javascript
复制
db.collection.createIndex({ content: "text" })
支持多字段联合文本索引:
javascript
复制
db.collection.createIndex({ title: "text", description: "text" })
- 地理空间索引(Geospatial Index)
2dsphere:支持球面几何查询(如经纬度):
javascript
复制
db.places.createIndex({ location: "2dsphere" })
2d:支持平面几何查询(适用于旧版本)。
- 哈希索引(Hashed Index)
对字段值计算哈希后创建索引,常用于分片键:
javascript
复制
db.collection.createIndex({ field: "hashed" })
- TTL 索引(Time-To-Live Index)
自动删除过期文档(如日志数据):
javascript
复制
db.logs.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })
- 唯一索引(Unique Index)
确保字段值唯一:
javascript
复制
db.users.createIndex({ email: 1 }, { unique: true })
- 稀疏索引(Sparse Index)
仅索引包含该字段的文档:
javascript
复制
db.users.createIndex({ phone: 1 }, { sparse: true })
三、索引管理
- 查看索引
javascript
复制
db.collection.getIndexes() // 查看集合的所有索引
- 删除索引
javascript
复制
db.collection.dropIndex("indexName") // 删除指定索引
db.collection.dropIndexes() // 删除所有索引(保留 _id 索引)
- 重建索引
javascript
复制
db.collection.reIndex() // 重建所有索引(慎用,可能阻塞操作)
四、索引使用策略
- 索引选择
MongoDB 查询优化器会自动选择最优索引。
可通过 explain() 分析查询执行计划:
javascript
复制
db.collection.find({ field: "value" }).explain("executionStats")
- 覆盖查询(Covered Query)
如果查询结果完全由索引字段提供,无需回表查文档:
javascript
复制
// 创建复合索引
db.users.createIndex({ name: 1, age: 1 })
// 覆盖查询示例
db.users.find({ name: "Alice" }, { _id: 0, name: 1, age: 1 })
- 索引交集(Index Intersection)
MongoDB 可以将多个索引的结果合并,但通常复合索引更高效。
五、索引的限制与注意事项
内存占用:
索引存储在内存中,大集合的索引可能占用较多内存。
写操作开销:
索引会降低插入、更新、删除操作的性能。
索引键大小限制:
索引键(Index Key)的总大小不能超过 1024 字节。
查询模式匹配:
某些查询可能无法使用索引(如正则表达式未左锚定)。
六、最佳实践
优先使用复合索引:避免创建过多单字段索引。
避免全集合扫描:对高频查询字段建立索引。
索引选择性:高基数(唯一值多)的字段更适合建索引。
监控索引使用:
javascript
复制
db.collection.aggregate([{ $indexStats: {} }])
删除冗余索引:定期清理未使用的索引。
示例场景
场景 1:查询优化
javascript
复制
// 创建复合索引
db.orders.createIndex({ customerId: 1, orderDate: -1 })
// 查询最近订单
db.orders.find({ customerId: 123 }).sort({ orderDate: -1 })
场景 2:唯一约束
javascript
复制
// 确保用户名唯一
db.users.createIndex({ username: 1 }, { unique: true })
通过合理设计索引,可以显著提升 MongoDB 的查询性能,但需根据实际场景权衡读写开销。