MongoDB 在 Debian 上的查询性能优化指南
一 硬件与操作系统层优化
- 使用SSD/NVMe替代机械盘,显著降低查询与写入的 I/O 延迟。
- 保证充足内存,让热点数据与索引尽量常驻内存,减少磁盘访问。
- 合理设置 Swap 与内核参数:创建适度大小的 Swap,降低 vm.swappiness,避免频繁换页影响查询稳定性。
- 选择多核 CPU与更高网络带宽,提升并发查询与结果返回速度。
- 采用合适的 RAID(如 RAID10)提升磁盘吞吐与可靠性。
- 运行64 位MongoDB,支持更大的内存映射与数据集规模。
二 存储引擎与缓存配置
- 使用 WiredTiger 存储引擎,并在 /etc/mongod.conf 中调整 storage.wiredTiger.engineConfig.cacheSizeGB,一般设置为“可用内存的约 50%–60%”(需为系统与其他进程预留内存)。
- 避免创建不必要的索引,减少写放大与缓存压力。
- 如仍使用 MMAPv1(旧版本),可启用 storage.mmapv1.smallFiles 降低内存占用(新部署建议使用 WiredTiger)。
三 索引策略与查询优化
- 为高频查询条件创建单字段索引与复合索引,复合索引遵循“等值在前、范围在后”的顺序,提升多条件过滤效率。
- 优先设计覆盖索引(查询字段全部包含在索引中),避免回表访问文档。
- 使用 explain(“executionStats”) 检查是否命中索引、是否发生 COLLSCAN,并据此调整索引。
- 精简查询:只返回必要字段(投影),使用 limit() 限制返回条数,避免大结果集传输与处理开销。
- 优化语句:尽量避免全表扫描与无限制正则;对复杂处理用聚合管道替代多次往返查询。
- 必要时用 hint() 指定更优索引;删除不再使用的索引,减少维护成本。
- 示例:
- 创建复合索引:
db.orders.createIndex({ userId: 1, orderDate: -1 })
- 覆盖查询:
db.orders.find({ userId: 123 }, { userId: 1, total: 1, _id: 0 })
- 执行计划:
db.orders.find({ userId: 123 }).explain("executionStats")
四 部署架构与读写策略
- 读多写少场景启用副本集读偏好,将 read preference 设为 secondaryPreferred,在从节点分担读负载。
- 写一致性要求不高时,适度降低 Write Concern 以提升写入与查询的整体吞吐。
- 数据量大或并发高时引入分片,按高基数字段(如 userId)进行分片:
sh.enableSharding("myDB"); sh.shardCollection("myDB.orders", { userId: 1 })。
- 副本集提供高可用与故障切换,保障查询稳定性。
五 监控、诊断与维护
- 使用 mongostat、mongotop 观察 QPS、连接数、I/O 与耗时分布,快速定位瓶颈。
- 启用 Profiler 记录慢查询:
db.setProfilingLevel(1, { slowms: 100 }),定期分析并优化。
- 定期审查与清理索引:用
getIndexes() 查看使用情况,删除无用索引;必要时对大集合采用后台重建索引以减少阻塞。
- 适度清理日志,避免磁盘占满影响服务。
- 任何配置变更先在测试环境验证,再滚动上线,确保稳定性。