玩转mongoDB(六):索引,速度的引领(普通索引篇)

玩转mongoDB(六):索引,速度的引领(普通索引篇)
最新回答
花Ж葬

2026-03-20 11:41:25

MongoDB索引通过优化数据检索路径显著提升查询性能,合理使用不同类型的索引可实现查询速度的数量级提升。 以下从索引类型、创建方法、性能对比及管理策略四个方面展开说明:

一、普通索引:单字段查询加速
  • 核心原理:在指定字段建立索引后,数据库可直接通过索引定位数据,避免全表扫描。例如在person集合的age字段创建升序索引:db.person.ensureIndex({"age":1}) // 1表示升序,-1表示降序
  • 性能对比:

    无索引:查询耗时962毫秒,扫描200万条文档,执行类型为COLLSCAN(全表扫描)。

    有索引:查询耗时143毫秒,仅扫描2000条文档,执行类型为FETCH+IXSCAN(索引扫描+文档检索),速度提升约7倍(1个数量级)。

二、复合索引:多条件查询优化
  • 适用场景:当查询条件涉及多个字段时(如age和name),复合索引可显著减少扫描范围。
  • 性能对比:

    单键索引:查询age在20-30岁且name为ryan1的文档时,强制使用age索引耗时2031毫秒,需扫描200万条文档。

    复合索引:使用{"age":1, "name":1}索引耗时仅8毫秒,仅扫描2010条文档,速度提升254倍(2个数量级)。

  • 排序优化:复合索引的字段顺序影响排序性能。例如:

    错误顺序:{"age":1, "name":1}索引下对name排序需内存排序,耗时6882毫秒。

    正确顺序:{"name":1, "age":1}索引下直接利用索引排序,耗时3毫秒,扫描2100条文档。

三、唯一索引:数据唯一性约束
  • 单字段唯一索引:确保字段值唯一(如name字段):db.person.ensureIndex({"name":1}, {"unique":true})
  • 复合唯一索引:字段组合值唯一(如name和age组合):db.person.ensureIndex({"name":1, "age":1}, {"unique":true})
  • 验证方法:通过db.person.getIndexes()查看索引列表,确认unique:true属性。
四、稀疏索引:可选字段优化
  • 核心特性:仅对包含索引字段的文档生效,避免因null值导致唯一性冲突。例如:db.person.ensureIndex({"mobilephone":1}, {"unique":true, "sparse":true})
  • 非唯一稀疏索引:移除unique选项即可创建非唯一稀疏索引,减少索引存储开销。
五、索引管理:创建、查看与删除
  • 创建方法:

    ensureIndex(旧版)与createIndex(新版)功能相同,推荐使用后者:db.person.createIndex({"age":1})

  • 查看索引:db.person.getIndexes() // 返回集合所有索引信息
  • 删除索引:db.person.dropIndex("name_1") // 删除名为`name_1`的索引
  • 优化策略:

    定期评估:业务变化可能导致索引失效,需通过explain("executionStats")分析查询性能。

    删除冗余索引:如单键索引可能被复合索引替代,减少写入开销。

关键参数解析(explain("executionStats"))
  • executionTimeMillis:查询总耗时,直接反映性能差异。
  • totalDocsExamined:扫描文档数,索引优化后应显著降低。
  • stage:执行类型,IXSCAN表示索引扫描,COLLSCAN表示全表扫描。
  • totalKeysExamined:扫描索引键数,复合索引可大幅减少此值。

总结:MongoDB索引类型多样,普通索引加速单字段查询,复合索引优化多条件与排序,唯一索引保障数据唯一性,稀疏索引处理可选字段。通过createIndex创建、getIndexes查看、dropIndex删除,结合explain分析性能,可动态调整索引策略以适应业务需求。