二、索引基础
2.1 单字段索引
db.products.createIndex({ price: 1 })
db.products.createIndex({ createdAt: -1 })
db.products.find({ price: { $gt: 100 } })
2.2 复合索引
db.orders.createIndex({ status: 1, createdAt: -1 })
db.orders.find({ status: "completed" })
db.orders.find({ status: "pending", createdAt: { $gt: ISODate() } })
db.orders.find({ status: "pending" }).sort({ createdAt: -1 })
db.orders.find({ createdAt: { $gt: ISODate() } })
三、索引策略
3.1 ESR 原则
Equality(等值) → Sort(排序) → Range(范围)
db.orders.createIndex({ status: 1, createdAt: -1, amount: 1 })
db.orders.find({
status: "completed",
amount: { $gt: 100 }
}).sort({ createdAt: -1 })
3.2 覆盖查询
db.orders.createIndex({ status: 1, customerId: 1, amount: 1 })
db.orders.find(
{ status: "completed", customerId: ObjectId("...") },
{ status: 1, customerId: 1, amount: 1, _id: 0 }
)
四、执行计划与诊断
4.1 explain()
db.products.find({ price: 50 }).explain("executionStats")
4.2 慢查询日志
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ millis: -1 }).limit(10)
五、高级索引
5.1 多键索引
db.products.createIndex({ tags: 1 })
db.products.find({ tags: "electronics" })
db.products.find({ tags: { $all: ["electronics", "smartphones"] } })
5.2 文本索引
db.articles.createIndex({ content: "text", title: "text" })
db.articles.find(
{ $text: { $search: "mongodb indexing" } },
{ score: { $meta: "textScore" } }
).sort({ score: { $meta: "textScore" } })
5.3 部分索引
db.orders.createIndex(
{ status: 1, createdAt: 1 },
{ partialFilterExpression: { status: { $ne: "draft" } } }
)
5.4 稀疏索引
db.users.createIndex(
{ phone: 1 },
{ sparse: true }
)
六、索引维护
6.1 查看索引
db.products.getIndexes()
db.products.totalIndexSize()
6.2 删除索引
db.products.dropIndex("price_1")
db.products.dropIndexes()
6.3 重建索引
db.products.reIndex()
七、性能优化实战
7.1 场景一:电商产品查询
db.products.explain().find({
category: "electronics",
price: { $gt: 100, $lt: 500 }
}).sort({ rating: -1, createdAt: -1 })
db.products.createIndex({
category: 1,
price: 1,
rating: -1,
createdAt: -1
})
7.2 场景二:订单聚合
db.orders.createIndex({
status: 1,
customerId: 1,
orderDate: 1,
totalAmount: 1
})
db.orders.aggregate([
{ $match: { status: "completed", orderDate: { $gte: startDate } } },
{ $group: { _id: "$customerId", total: { $sum: "$totalAmount" } } },
{ $sort: { total: -1 } }
])
八、最佳实践
- 避免索引过多:索引占用内存与存储
- 优先使用复合索引:复用率高
- 遵循 ESR 原则:等值→排序→范围
- 定期分析执行计划:及时发现慢查询
- 监控索引使用情况:删除未使用索引