索引是 MongoDB 提升查詢效能的核心機制。本文系統整理索引建立、查詢分析、複合/唯一/稀疏/TTL/地理空間等進階類型、管理指令與實務優化策略,並附實測效能對比。
測試環境:20 萬筆文件,查詢 id: 80000
db.persons.find({id:80000}).explain() → 101 ms(全集合掃描 COLLSCAN)db.persons.ensureIndex({id:1}) → <1 ms(索引掃描 IXSCAN)結論:索引可將點查效能提升 100 倍以上。
// 單欄升序/降序
db.collection.createIndex({ field: 1 }) // 1=升序, -1=降序
// 複合索引(欄位順序決定查詢匹配優先級)
db.collection.createIndex({ field1: 1, field2: -1 })
// 指定索引名稱
db.collection.createIndex({ name: 1 }, { name: "personName" })
注意:MongoDB 3.0+ 建議使用
createIndex(),ensureIndex()已棄用但仍相容。
| 類型 | 建立語法 | 適用場景 | 關鍵限制 |
|---|---|---|---|
| 唯一索引 | {unique: true} |
業務主鍵、Email、身分證號等不可重複欄位 | 插入重複值會報錯;可搭配 dropDups: true 清理既有重複(慎用) |
| 稀疏索引 | {sparse: true} |
欄位大量缺失(如 optional 欄位),避免索引膨脹 | 不索引缺失該欄位的文件;查詢該欄位為 null 時不會命中 |
| TTL 索引 | {expireAfterSeconds: 3600} |
Session、日誌、驗證碼等自動過期資料 | 僅支援單欄日期型別;背景執行緒每 60 秒掃描一次,非即時刪除 |
| 地理空間 2dsphere | {location: "2dsphere"} |
經緯度查詢、附近搜尋、範圍多邊形 | 欄位必須為 GeoJSON 格式 |
| 文字索引 | {content: "text"} |
全文搜尋、關鍵字檢索 | 每集合僅能建一個文字索引;支援權重、語言設定 |
| 雜湊索引 | {_id: "hashed"} |
分片鍵、高基數欄位均勻分佈 | 不支援範圍查詢,僅等值匹配 |
// 查看所有索引
db.collection.getIndexes()
// 查看索引大小統計
db.collection.stats().indexSizes
// 指定查詢使用特定索引
db.collection.find({...}).hint({ field: 1 })
// 異步建立索引(大量資料避免鎖表)
db.collection.createIndex({ field: 1 }, { background: true })
// 刪除單一索引
db.collection.dropIndex("index_name")
// 刪除所有索引(保留 _id)
db.collection.dropIndexes()
db.collection.aggregate([{$indexStats: {}}]) 找出長期未使用索引並移除。system.indexes 集合儲存所有索引元資料,可直接查詢:
db.system.indexes.find({ns: "db.collection"})
MongoDB 索引功能豐富且靈活,關鍵在於依查詢模式設計索引,而非依資料結構。善用 explain() 分析執行計畫、indexStats 監控使用率、background 避免鎖表,建立「建立→觀測→調整」的索引生命週期管理機制。