温馨提示×

Ubuntu中MongoDB索引优化技巧有哪些

小樊
35
2025-12-26 12:44:07
栏目: 云计算

Ubuntu下MongoDB索引优化实用技巧

一 基础与通用原则

  • 为高频出现在查询条件排序聚合管道早期阶段的字段建立索引,避免全表扫描(COLLSCAN)。
  • 优先设计复合索引并遵循“等值在前,范围在后”的顺序;将选择性更高的字段放在前面,提升索引命中率。
  • 利用覆盖索引(查询字段全部包含在索引中)避免回表,显著降低响应时间。
  • 控制索引数量,权衡读写性能:索引会加速读,但会拖慢写并占用空间
  • 后台创建索引以减少对线上业务的影响:db.collection.createIndex({...}, {background: true})
  • 定期清理不再使用或重复的索引,减少维护成本与存储占用。

二 索引类型与适用场景

索引类型 典型场景 示例
单字段索引 单条件精确查询 db.users.createIndex({name: 1})
复合索引 多条件查询与排序组合 db.users.createIndex({age: 1, name: -1})
唯一索引 字段值需唯一(如邮箱、用户名) db.users.createIndex({email: 1}, {unique: true})
部分索引 只为满足特定条件的文档建索引,减小体积 db.users.createIndex({name: 1}, {partialFilterExpression: {status: "active"}})
文本索引 全文检索 db.articles.createIndex({content: "text"})
地理空间索引 地理位置查询(2dsphere 支持球面几何) db.places.createIndex({location: "2dsphere"})

三 查询设计与索引利用

  • 使用 explain("executionStats") 检查是否走索引、是否发生 COLLSCAN,并关注 totalKeysExaminedtotalDocsExaminedexecutionTimeMillis 等关键指标。
  • 对排序与范围条件,确保索引顺序与查询一致;排序字段尽量放在复合索引的中间或末尾以匹配执行计划。
  • 尽量实现覆盖索引,只返回需要的字段,避免回表访问。
  • 分页避免深翻页:优先使用基于索引的游标分页(如记录上一页的排序值),谨慎使用 skip/limit 的大偏移。
  • 必要时用 hint() 指定更优索引,或通过 indexFilterSet 验证索引过滤器的效果。
  • 对聚合管道,尽量把能利用索引的 $match/$sort 提前,减少后续阶段的数据量。

四 监控与维护

  • 启用慢查询分析db.setProfilingLevel(1, {slowms: 100}) 记录超过阈值的操作;db.system.profile.find().sort({millis: -1}) 定位最慢语句。
  • 使用 mongostat / mongotop 观察索引命中、锁等待与读写热点,配合 explain 做针对性优化。
  • 结合 Ubuntu 日志定位问题:tail -f /var/log/mongodb/mongod.log 实时查看耗时命令;必要时执行 db.runCommand({logRotate: 1}) 轮转日志。
  • 索引碎片或大量更新后,按需执行 重建索引db.collection.reIndex()(注意会占用资源与锁)。
  • 合理设置 WiredTiger 缓存(如 storage.wiredTiger.engineConfig.cacheSizeGB),避免频繁换页影响索引与查询性能。

五 实用命令清单

  • 创建索引(含后台与命名):
    • db.users.createIndex({name: 1}, {background: true, name: "idx_name"})
  • 复合、唯一、部分、文本与2dsphere索引:
    • db.users.createIndex({age: 1, name: -1})
    • db.users.createIndex({email: 1}, {unique: true})
    • db.users.createIndex({name: 1}, {partialFilterExpression: {status: "active"}})
    • db.articles.createIndex({content: "text"})
    • db.places.createIndex({location: "2dsphere"})
  • 查看与删除索引:
    • db.users.getIndexes()
    • db.users.dropIndex("idx_name")db.users.dropIndexes()(保留 _id 索引)
  • 执行计划与性能分析:
    • db.users.find({name: "Alice"}).explain("executionStats")
    • db.setProfilingLevel(1, 100); db.system.profile.find().sort({millis: -1})

0