核心原则:索引需针对高频查询字段设计,优先覆盖where、sort、join($lookup)操作的关键字段。
transactions集合的userid字段创建升序索引:db.transactions.createIndex({ userid: 1 });
userid筛选且按create_time排序),需遵循最左前缀原则(查询条件需包含索引左侧连续字段)。例如,为userid(筛选)和create_time(排序)创建复合索引:db.transactions.createIndex({ userid: 1, create_time: -1 }); // 1表示升序,-1表示降序
2dsphere索引(如位置附近查询);全文搜索用text索引(如商品名称模糊搜索);数组字段用多键索引(自动为数组每个元素创建索引)。关键工具:使用explain()方法查看查询执行计划,重点关注winningPlan(是否使用索引)和executionStats(索引命中率、扫描文档数)。
db.transactions.find({ userid: "user123" }).explain("executionStats");
结果中winningPlan.inputStage.stage若为IXSCAN(索引扫描),则表示使用了索引;若为COLLSCAN(全表扫描),则需优化索引。db.collection.aggregate([{ $indexStats: {} }])查看索引的accesses.ops(操作次数)和accesses.since(上次使用时间),识别长期未使用的索引。reIndex()命令重建集合索引(需停机或低峰期操作):db.transactions.reIndex();
userid字段的单字段索引(若有userid_1_create_time_-1复合索引):db.transactions.dropIndex("userid_1");
explain()验证后再添加。userid和amount创建复合索引,查询时仅返回这两个字段:db.transactions.find({ userid: "user123" }, { userid: 1, amount: 1, _id: 0 }).explain("executionStats");
结果中executionStats.totalDocsExamined应为0(表示未扫描文档),totalKeysExamined为扫描的索引键数量。{ userid: 1, create_time: -1 },查询时需按相同顺序排序:db.transactions.find({ userid: "user123" }).sort({ create_time: -1 }); // 正确,使用索引
db.transactions.find({ userid: "user123" }).sort({ userid: 1, create_time: -1 }); // 更优,完全匹配索引顺序
limit()减少结果集大小;使用投影({ field: 1 })排除不需要的字段(如_id),降低网络传输压力。mongostat(监控操作速率)和mongotop(监控集合级读写时间)工具,识别慢查询和索引瓶颈。例如,mongotop显示transactions集合的read时间过长,需检查其索引。