1. 分析查询模式,精准创建索引
优化索引的第一步是理解应用程序的查询模式。通过监控工具(如mongostat、mongotop)或db.currentOp()查看高频查询,识别需要索引的字段。例如,若经常根据username字段查询用户信息,可创建单字段索引:db.users.createIndex({ username: 1 });若需联合查询name和age并按name排序,可创建复合索引:db.users.createIndex({ name: 1, age: -1 })(复合索引字段顺序需匹配查询条件,选择性高的字段优先)。
2. 选择合适的索引类型
根据数据特性和查询需求选择索引类型:
find({ age: 25 }));find({ name: "John", age: 25 }));tags数组);find({ location: { $near: [ -73.856077, 40.848447 ] } }));find({ description: "mongodb debian" }));createIndex({ expireAt: 1 }, { expireAfterSeconds: 0 }))。3. 利用覆盖索引减少IO
覆盖索引是指查询所需的所有字段都包含在索引中,MongoDB可直接从索引中获取数据,无需访问实际文档。例如,若查询只需name和age字段,可创建包含这两个字段的复合索引:db.users.createIndex({ name: 1, age: 1 }),然后通过explain("executionStats")确认isCovered为true。
4. 定期维护索引性能
db.collection.reIndex()重建索引(大数据量集合建议后台创建,如db.users.reIndex({ background: true }));db.collection.getIndexes()查看所有索引,删除不再使用的索引(如db.users.dropIndex("username_1")),减少写操作开销和存储占用。5. 使用explain()分析查询计划
通过explain("executionStats")查看查询的执行细节,重点关注:
winningPlan中的inputStage是否使用了索引(如IXSCAN表示使用了索引);executionStats.totalDocsExamined(扫描文档数)应远小于集合总文档数;executionStats.nReturned(返回文档数)是否符合预期;executionStats.executionTimeMillis(执行时间)是否过长。6. 优化索引设计原则
name的唯一值比age多,复合索引应为{ name: 1, age: 1 });7. 硬件与配置优化
/etc/mongod.conf中的storage.wiredTiger.engineConfig.cacheSizeGB参数(建议设置为物理内存的50%-70%),提高缓存命中率。