前缀为唯一字段的复合索引是否有意义?以_id为例分析
以_id为前缀的复合索引是否有实际意义?
首先明确:MongoDB默认会给所有集合创建唯一的单键索引{_id: 1},而且_id字段全局唯一,仅凭_id就能精准定位到单条文档。
大部分场景下,这个复合索引没必要
单独的{_id: 1}索引已经能满足绝大多数基于_id的查询需求——不管是单条查询还是批量查询,它都能快速定位文档。而{_id: 1, A: 1}这种复合索引,不仅会占用更多存储空间,还会增加写入操作时的索引维护成本,实际性能不会比单键索引更好。
唯一更高效的场景:覆盖索引查询
只有当你的查询只需要返回_id和字段A,不需要读取完整文档时,这个复合索引才能发挥作用,此时它属于「覆盖索引」,可以直接从索引中返回所需数据,无需回表读取文档,性能会比单独的_id索引更高。
举个查询示例:
db.collection.find( { _id: ObjectId("60d21b4667d0d8992e610c85") }, // 按_id精准查询 { A: 1, _id: 1 } // 仅返回_id和A字段 )
批量查询的场景同理:
db.collection.find( { _id: { $in: [ObjectId("60d21b4667d0d8992e610c85"), ObjectId("60d21b4667d0d8992e610c86")] } }, { A: 1, _id: 1 } )
这种情况下,MongoDB会直接从{_id:1,A:1}复合索引中提取数据,不用访问文档所在的磁盘块,速度更快。
如果查询需要返回除_id和A之外的其他字段,那这个复合索引就和单键_id索引没区别了——都需要回表读取完整文档,此时复合索引的额外存储和维护成本反而成了负担。
内容的提问来源于stack exchange,提问作者Bear Bile Farming is Torture
相关产品推荐
相关产品推荐

