MongoDB在Linux上的索引优化策略
使用explain()方法(如db.collection.find(query).explain("executionStats"))分析查询执行计划,重点关注“winningPlan”中的索引使用情况(如IXSCAN表示使用了索引,COLLSCAN表示全表扫描)。通过诊断查询模式,仅为频繁查询的字段或高频组合字段创建索引,避免过度索引(如为每个字段都建索引会增加写入开销)。
复合索引是提升多字段查询性能的关键,设计时需遵循最左前缀原则:
status字段只有“active”“inactive”两种值,选择性远高于create_time);>、<、between)和排序字段应放在复合索引的最后(如查询{status: "active", create_time: {$gt: ISODate("2025-01-01")}}.sort({create_time: 1}),复合索引应为{status: 1, create_time: 1});{a: 1, b: 1},再建{a: 1}属于冗余)。选择性高的字段(即字段值唯一性高的字段,如user_id、email)创建索引能更有效地过滤文档。例如,user_id的唯一性远高于gender,为user_id建索引能大幅减少扫描的文档数量。可通过db.collection.stats().indexDetails查看索引的选择性。
覆盖索引是指查询所需的所有字段都包含在索引中,无需回表读取文档(如查询{status: "active"}只需返回status字段,而索引已包含该字段)。创建覆盖索引的语法为:db.collection.createIndex({field1: 1, field2: 1}, {projection: {field1: 1, field2: 1}})。覆盖索引能显著减少I/O开销,提升查询速度。
db.collection.reIndex()命令重建碎片化的索引(如频繁插入、删除数据会导致索引碎片化,影响查询性能);db.collection.getIndexes()查看现有索引,删除不再使用的索引(如旧查询对应的索引);compact命令压缩数据文件,减少索引占用的磁盘空间。通过db.collection.aggregate([{ $indexStats: {} }])命令监控索引的使用频率(如accesses.ops表示索引被访问的次数)、命中率(命中率低说明索引未被有效利用)。根据监控结果调整索引策略(如删除未使用的索引,优化低命中率的索引)。
$ne、$nin操作符:这些操作符无法有效利用索引(如db.collection.find({status: {$ne: "inactive"}})会扫描全表);$or查询:$or查询通常无法利用复合索引(除非每个子句都有对应的索引);status字段经常变更)会导致索引重建,影响写入性能。storage.wiredTiger.engineConfig.cacheSizeGB参数)足够大,能容纳常用索引和数据(建议设置为物理内存的50%-70%);echo never > /sys/kernel/mm/transparent_hugepage/enabled命令关闭)。