1. 诊断查询模式:明确优化方向
优化索引的第一步是了解应用的查询习惯。使用explain("executionStats")方法分析常用查询的执行计划,重点关注totalDocsExamined(扫描文档数)、executionStages.stage(是否使用索引,如IXSCAN表示索引扫描,COLLSCAN表示全表扫描)等指标。例如,若查询db.users.find({username: "admin", status: "active"})的stage为COLLSCAN,则说明缺少合适的索引。
2. 精准创建索引:匹配查询需求
db.users.createIndex({username: 1})(1表示升序,-1表示降序)。db.orders.find({status: "shipped", create_time: {$gt: ISODate("2023-01-01")}}).sort({price: 1}),应创建复合索引{status: 1, create_time: 1, price: 1}(等值status在前,范围create_time居中,排序price在后)。db.users.find({_id: {$gt: 1000}}, {_id: 1, name: 1, email: 1}),可创建索引{_id: 1, name: 1, email: 1},使MongoDB直接从索引中获取数据,无需访问文档。3. 删除冗余索引:减少资源消耗
使用db.collection.getIndexes()查看集合的所有索引,删除不再使用的索引。例如,若曾经为email字段创建了索引但后续查询不再使用,可执行db.users.dropIndex({email: 1})。过多的索引会增加写入开销(每次插入/更新需维护索引)和存储空间。
4. 使用索引提示:强制优化查询
若explain()显示MongoDB未选择最优索引,可使用hint()方法强制指定索引。例如,db.users.find({username: "admin"}).hint({username: 1})强制使用username字段的索引。需谨慎使用,避免人为干预导致性能下降。
5. 定期重建索引:优化碎片性能
随着数据的增删改,索引会产生碎片,降低查询效率。使用db.collection.reIndex()重建索引,优化索引结构。例如,db.users.reIndex()会重新构建users集合的所有索引。建议在低峰期执行,避免影响线上业务。
6. 监控与动态调整:持续优化性能
db.collection.aggregate([{ $indexStats: {} }])查看索引的使用频率(accesses.ops表示访问次数)、最后一次访问时间(accesses.timestamp),识别未使用的索引。status字段的索引很少被访问,可考虑删除。7. 硬件与环境优化:提升索引效率
8. 高级技巧:进一步提升性能
db.users.dropIndex({username: 1}) → 批量插入数据 → db.users.createIndex({username: 1})。