温馨提示×

Debian MongoDB索引优化策略有哪些

小樊
42
2025-12-11 05:37:14
栏目: 云计算

Debian上MongoDB索引优化策略

一 基础与索引类型选择

  • 明确查询模式后按需选择索引类型:
    • 单键索引用于单字段高频查询;
    • 复合索引用于多条件组合查询(最多支持32个键);
    • 多键索引自动为数组元素建立索引;
    • 文本索引用于字符串全文检索(一个集合仅支持一个文本索引);
    • 地理空间索引 2dsphere/2d用于地理位置查询;
    • 哈希索引用于等值查询与分片键的均匀分布;
    • TTL 索引用于按时间自动过期清理数据。
  • 结合选择性:优先为高选择性字段建索引,低选择性字段(如状态位)宜与其它字段组合成复合索引。
  • 在 Debian 上的创建方式与通用平台一致,示例:db.products.createIndex({ "category": 1, "item": 1 })

二 复合索引设计与ESR规则

  • 遵循 ESR 规则(Equality → Sort → Range) 安排复合索引字段顺序:
    • 等值条件字段放最左;
    • 排序字段放中间(注意与查询的排序方向一致);
    • 范围条件(如 $gte/$lte/$in)放最右。
  • 典型示例:
    • 查询:find({"a":1, "b":2, "c":{$gte:1}}).sort({"d":1,"e":-1})
      建议索引:{a:1, b:1, d:1, e:-1, c:1}
  • 多字段排序方向需与索引一致:sort({"a":1,"b":-1}) 需要索引 {a:1,b:-1}
  • 等值+非等值组合应将等值字段放左:find({"a":{$gte:1}, "b":1}) 更优索引为 {b:1, a:1}
  • 同一字段的升/降序排序只需一个索引(MongoDB可双向扫描)。

三 查询与索引协同优化

  • 优先构造覆盖查询(Covered Query):将查询与投影字段全部包含在索引中,避免回表;注意默认返回的 _id 要么投影排除,要么加入索引。
  • 仅返回需要的字段(投影),减少网络与内存开销:db.posts.find({}, {timestamp:1,title:1,author:1,abstract:1})
  • 使用 explain("executionStats") 检查是否走索引与扫描量:
    • 关注 COLLSCAN(全表扫描)与 DocsExamined/KeysExamined
    • 理想情况:nReturned ≈ totalKeysExamined ≈ totalDocsExamined
  • 特殊场景用 hint() 固定索引进行压测或规避优化器误选。
  • 字符串比较需匹配索引的排序规则 Collation:查询与索引的 collation 一致才能使用该索引。

四 特殊查询与索引策略

  • $or 查询:为每个子句分别建立最优索引,例如
    {$or:[{"a":1,"b":1},{"c":1,"d":1}]} 需索引 {a:1,b:1}{c:1,d:1},而不是一个大复合索引。
  • $or + Sort:可拆分为多个带排序的子查询并分别建索引,例如
    {$or:[{"a":1,"b":1},{"c":1,"d":1}]}.sort({"e":-1}) → 索引 {a:1,b:1,e:-1}{c:1,d:1,e:-1}
  • 部分索引(Partial Index):只为满足条件的文档建立索引,减小体积与维护成本,例如
    db.coll.createIndex({a:1}, {partialFilterExpression: {a:{$gt:5}}})
  • 去除冗余索引:删除不再使用或被其它索引包含的索引,降低写放大与内存占用。

五 运维与监控实践

  • 使用 慢日志定位问题查询,重点关注 DocsExamined/KeysExamined 与是否出现 COLLSCAN/SORT;据此新增或调整索引。
  • 索引维护与观测:
    • 查看与清理:getIndexes()dropIndex()dropIndexes()
    • 重建索引:reIndex()(大数据量谨慎,尽量在维护窗口进行);
    • 监控大小:totalIndexSize() 评估索引是否超出内存。
  • 资源与部署:
    • 保证足够内存SSD存储以降低 I/O;
    • 适度增加 WiredTiger 缓存(如调整 storage.wiredTiger.engineConfig.cacheSizeGB);
    • 读多写少场景可用读写分离read preference: secondaryPreferred);
    • 超大规模考虑分片副本集提升并发与可用性。
  • 批量导入阶段可延迟/后台建索引并采用批量写入,导入完成后再创建必要索引,减少维护开销。

0