索引是MongoDB查詢性能的核心保障,設計時需結合查詢模式與數據特征,遵循以下黃金法則:
user_id
、mobile
)創建索引,避免為低選擇性字段(如gender
)浪費資源;db.users.find({age: {$gt: 18}}, {name: 1, age: 1, _id: 0})
可通過索引完成);db.orders.createIndex({status: 1, orderDate: -1, amount: 1})
,其中status
為等值查詢、orderDate
為排序、amount
為范圍查詢);復合索引是提升多字段查詢效率的關鍵,需根據查詢場景設計字段順序:
db.users.find({username: "admin", email: "admin@example.com"}).sort({createTime: -1})
,復合索引{username: 1, email: 1, createTime: -1}
可完全覆蓋);{a: 1, b: 1}
,則無需單獨創建{a: 1}
(除非有特殊查詢需求);_id: 0
排除默認返回的_id
字段,進一步減少IO。根據業務需求創建特殊類型索引,解決特定問題:
db.logs.createIndex({createdAt: 1}, {expireAfterSeconds: 86400})
,7天后自動刪除過期日志);db.places.createIndex({location: "2dsphere"})
,用于“附近地點”查詢)。通過explain()
方法分析查詢執行計劃,識別索引使用問題:
winningPlan.stage
:若為COLLSCAN
(全表掃描),說明未使用索引;executionStats.totalKeysExamined
:索引鍵檢查數,數值過大表示索引效率低;executionStats.totalDocsExamined
:文檔檢查數,若遠大于返回結果數,說明索引未覆蓋查詢;executionStats.executionTimeMillis
:執行時間,超過100ms需優化;explain()
結果添加缺失索引、調整復合索引順序或修改查詢條件(如將$or
查詢改為$in
查詢,避免全表掃描)。db.collection.aggregate([{ $indexStats: {} }])
查看索引使用情況);$ne
、$not
、$nin
等操作符通常會導致全表掃描,盡量避免在查詢中使用;/abc/
),若需使用正則,盡量采用左錨定(如/^prefix/
),以便利用索引;mongostat
(監控操作速率)、mongotop
(監控集合級IO)或第三方工具(如Percona PMM)實時監控索引使用情況;db.collection.reIndex()
重建碎片化索引,保持索引性能(建議在低峰期操作);