1. 硬件資源優化
2. 配置文件調優
storage.wiredTiger.engineConfig.cacheSizeGB
設置為服務器總內存的50%-75%(需扣除系統和其他應用的內存占用),避免過大導致內存交換(swap)或過小無法緩存熱點數據。net.maxIncomingConnections
(默認10000)和net.maxOutgoingConnections
(默認10000),根據實際并發連接數適當增大,避免連接數限制導致的拒絕服務;同時設置合理的net.socketTimeoutMS
(默認30000ms)和net.connectTimeoutMS
(默認10000ms),避免因超時導致的連接堆積。operationProfiling
模塊開啟慢查詢監控,設置slowOpThresholdMs
(默認100ms)閾值,記錄執行時間超過閾值的查詢,便于后續優化;例如:operationProfiling.mode: "slowOp"
(僅記錄慢查詢)或"all"
(記錄所有操作)。storage.journal.enabled
設置為true
(默認開啟),保障數據一致性;在副本集中,合理配置replication.oplogSizeMB
(默認為磁盤空間的5%),確保oplog足夠大,避免因oplog過小導致的主從同步失敗。3. 索引優化
find
、sort
、aggregate
操作的字段創建索引,避免過度索引(每個索引會增加寫操作的開銷并占用磁盤空間);例如,對user_id
、order_date
等高頻查詢字段創建索引。{status: "active", create_time: {$gt: ISODate("2025-01-01")}}
),創建復合索引并將選擇性高的字段(如status
)放在前面,提高索引利用率;復合索引的字段順序需與查詢條件的字段順序一致。db.collection.createIndex({name: 1, age: 1}, {projection: {name: 1, age: 1}})
),使MongoDB無需訪問文檔即可返回結果,減少磁盤I/O;例如,查詢{name: "John", age: 30}
可使用覆蓋索引。db.collection.reIndex()
命令重新構建碎片化嚴重的索引,優化查詢性能;定期使用db.collection.getIndexes()
查看索引使用情況,刪除未使用或很少使用的索引(通過$indexStats
聚合命令分析)。4. 查詢優化
projection
參數僅返回所需字段,避免傳輸整個文檔;例如:db.users.find({status: "active"}, {_id: 0, name: 1, email: 1})
,僅返回name
和email
字段。$where
、$regex
等低效操作符(會導致全表掃描),盡量使用索引支持的查詢條件(如=
、$in
、$lt
);例如,用db.users.find({age: {$gte: 18}})
替代db.users.find({$where: "this.age >= 18"})
。match
、group
、sort
)組合成聚合管道,減少中間結果的生成和傳輸;例如,統計每月活躍用戶數:db.orders.aggregate([{ $match: {status: "completed"}}, { $group: { _id: {$month: "$create_time"}, count: {$sum: 1}}}, { $sort: {_id: 1}}])
。skip
和limit
分頁,當skip
值較大時(如超過1000),改用基于索引的range query
(如{create_time: {$lt: last_value}}
)替代,避免性能下降;例如,記錄上一頁最后一條記錄的create_time
,下一頁查詢{create_time: {$lt: last_create_time}, status: "active"}.limit(20)
。5. 分片與復制集優化
user_id
、order_date
),避免數據傾斜(如避免使用單調遞增的字段作為分片鍵,導致新數據集中在少數分片)。sh.status()
查看分片集群的狀態,確保各分片的負載均衡;若出現數據傾斜,可通過mergeChunks
或splitAt
命令調整分片范圍,或重新選擇分片鍵。6. 監控與診斷
mongostat
(實時顯示操作速率,如讀寫次數、延遲)和mongotop
(顯示集合級別的讀寫時間分布)監控數據庫性能,快速定位性能瓶頸;例如,mongostat -u admin -p password --authenticationDatabase admin 1
每秒刷新一次操作統計。db.setProfilingLevel(1, {slowOpThresholdMs: 100})
開啟慢查詢記錄,使用db.system.profile.find().sort({ts: -1}).limit(10)
查看最近的慢查詢,分析查詢的執行計劃(explain()
)和索引使用情況,針對性優化。