MongoDB 覆盖索引查询(Covered Query)
                           
天天向上
发布: 2025-03-09 09:24:14

原创
620 人浏览过

在 MongoDB 中,覆盖索引查询(Covered Query)是指查询所需的所有字段都可以直接从索引中获取,MongoDB 无需扫描文档(Documents),从而提高查询性能。


1. 覆盖索引查询的特点

  • 查询字段全部在索引中 → 避免访问实际文档,减少 I/O。
  • 索引必须包含所有查询字段(包括 find 条件字段、projection 返回字段)。
  • _id 字段默认存在索引,如果查询结果不包含 _id,可能需要显式排除它。

2. 创建覆盖索引

示例:创建集合

db.products.insertMany([
  { _id: 1, name: "Laptop", category: "Electronics", price: 1200 },
  { _id: 2, name: "Phone", category: "Electronics", price: 800 },
  { _id: 3, name: "Table", category: "Furniture", price: 150 }
])

① 创建索引

创建组合索引,包含 categoryprice 字段:

db.products.createIndex({ category: 1, price: 1 })

② 使用覆盖索引查询

查询 categoryprice,并排除 _id(避免扫描文档):

db.products.find({ category: "Electronics" }, { category: 1, price: 1, _id: 0 })

💡 为什么排除 _id

  • _id 默认有索引,但不在 { category: 1, price: 1 } 组合索引内,MongoDB 需要访问文档来获取 _id,导致查询无法完全覆盖索引。

3. 使用 explain() 验证

可以使用 .explain("executionStats") 检查查询是否是覆盖索引查询

db.products.find({ category: "Electronics" }, { category: 1, price: 1, _id: 0 }).explain("executionStats")

查看 explain 结果中的 "stage"

"stage": "PROJECTION_COVERED"

如果 "stage": "PROJECTION_COVERED",则表示完全使用索引,查询无需访问文档


4. 覆盖索引 vs. 非覆盖索引查询

查询方式是否使用索引是否访问文档适用场景
普通索引查询仅用于查找需要访问文档查询字段较多
覆盖索引查询直接获取结果无需访问文档查询字段较少,提高性能

5. 覆盖索引的优化技巧

使用组合索引(Compound Index),确保查询字段全部包含在索引中。
排除 _id 字段(如果不在索引内),避免额外的文档扫描。
适用于只查询少量字段的场景,例如统计、列表展示等。


6. 总结

  • 覆盖索引查询可以显著提高查询性能,避免文档扫描,减少 I/O。
  • 必须确保查询的字段都在索引中,否则 MongoDB 仍然会访问文档。
  • 使用 .explain("executionStats") 检查是否是覆盖索引查询,关键是 "stage": "PROJECTION_COVERED"

更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *