db.collection.createIndex()是创建单字段索引的唯一标准方法;仅当查询条件只含一个字段、该字段高频独立使用、值分布均匀且非数组字段时才适用;需注意字段名加引号、嵌入字段用点号、建索引后需验证执行计划。

db.collection.createIndex() 是创建单字段索引的唯一标准方法,不是可选,而是必须用它——其他写法(比如 ensureIndex)早已废弃,且在 4.4+ 版本中会报错或静默忽略。
什么时候该用单字段索引?
只在以下情况才适合建单字段索引:
- 查询条件里**只出现一个字段**,比如 find({ status: "active" }) 或 find({ user_id: 123 })
- 该字段查询频率高,但很少和别的字段组合使用
- 字段值分布较均匀(避免大量重复值,比如 is_deleted: false 这种布尔字段,选择性太低,效果有限)
- 不是数组字段(除非你明确需要对整个数组做等值匹配,而非数组内元素)
createIndex() 的参数陷阱
常见错误是把排序方向写错或漏掉,导致索引无法命中:
- 1 表示升序,-1 表示降序,两者在单字段索引中**对等值查询完全等效**,但会影响 $gt/$lt 类范围查询的扫描方向
- 字段名必须用字符串(带引号),尤其是嵌入式字段:"location.city" ✅,location.city ❌(会报语法错误)
- 不要加额外选项(如 { background: true })除非集合很大且不能阻塞写入——否则默认同步建索引更安全、更快完成
嵌入字段索引怎么写才生效?
点号(.)不是语法糖,是 MongoDB 解析嵌入路径的强制约定:
- db.users.createIndex({ "profile.age": 1 }) → 支持 find({ "profile.age": 25 })
- db.users.createIndex({ "profile": 1 }) → **不支持** find({ "profile.age": 25 }),只能用于 find({ profile: { ... } }) 全文档匹配
- 数组内嵌字段要小心:如果 tags 是字符串数组,"tags" 索引支持 { tags: "mongodb" };但如果 tags 是对象数组,就得用 "tags.name" 这种写法
真正容易被忽略的是:索引建完不会自动生效于旧查询计划。如果之前执行过慢查询,MongoDB 可能还缓存着全表扫描的执行计划,需要运行 db.collection.explain("executionStats").find(...) 确认是否用了新索引,必要时用 db.collection.deleteIndexes() 清掉旧索引再重建。


















