MongoDB在Ubuntu上的索引策略
在Ubuntu系统上部署MongoDB时,索引策略的核心是通过合理设计索引结构、优化查询匹配及持续维护,平衡查询性能与系统开销(如存储、写入延迟)。以下是具体策略的详细说明:
索引的设计需紧密贴合应用的查询模式(如常用查询字段、排序需求、返回字段)。优先为高频查询字段(如userid、order_status)、排序字段(如create_time降序)及范围查询字段(如age > 18)创建索引。例如,若应用经常通过userid查询交易记录,可创建单字段索引:db.transactions.createIndex({userid: 1});若需同时查询userid和create_time并按时间排序,可创建复合索引:db.transactions.createIndex({userid: 1, create_time: -1})。
复合索引(Compound Index)的字段顺序需遵循ESR规则(Equality-Sort-Range):
=条件的字段放在最前面(如userid);sort()操作的字段(如create_time);>、<、in等范围条件的字段(如age)。userid = 123且create_time在最近7天的记录,复合索引{userid: 1, create_time: -1}能最大化利用索引,避免全表扫描。根据数据类型和查询需求选择合适的索引类型:
db.users.find({username: "john"}));db.orders.find({userid: 1, status: "paid"}).sort({create_time: -1}));tags数组),MongoDB会为数组每个元素创建索引键;location字段的$near操作);content字段的$text查询);expireAt字段,设置文档存活时间)。**覆盖查询(Covered Query)**是指查询的所有字段(包括过滤、排序、返回字段)均包含在索引中,无需访问原始文档。通过explain("executionStats")查看totalDocsExamined字段,若值为0则表示查询被覆盖。例如,若查询只需userid和create_time,可将这两个字段加入复合索引:db.transactions.createIndex({userid: 1, create_time: -1, amount: 1}),并确保查询中排除_id字段(或将其加入索引)。
索引虽能提升查询性能,但会增加写入开销(每次插入、更新需维护索引)和存储成本。定期使用db.collection.stats()查看索引大小,或通过$indexStats聚合管道(db.collection.aggregate([{ $indexStats: {} }]))分析索引使用频率(如accesses.ops表示索引被访问的次数)。删除未使用或低使用率的索引(如30天内未被访问的索引),以释放资源。
db.collection.reIndex()命令重建索引,减少碎片;db.collection.stats().indexDetails.<index_name>.frag查看碎片率,若超过30%建议重建。使用MongoDB自带工具监控索引性能:
winningPlan.inputStage.stage为IXSCAN表示使用了索引);mongostat监控索引操作速率(如idx miss表示索引未命中次数),mongotop查看集合级别的读写时间分布;db.orders.createIndex({status: 1}, {partialFilterExpression: {status: "pending"}})),减少索引大小;metadata子文档的不同键),但需谨慎使用(避免替代针对性索引);storage.wiredTiger.engineConfig.cacheSizeGB(设置为物理内存的50%-75%),确保索引能缓存在内存中,提升访问速度。