MongoDB 使用 B-Tree 索引加速查詢與排序。合理的索引策略能將查詢效能提升數個數量級,但過多索引會拖慢寫入速度,需在讀寫比例間取得平衡。
// 插入 20 萬筆測試資料
for (var i = 0; i < 200000; i++) {
db.books.insert({ number: i, name: i + "book" });
}
// 建立索引前後效能對比
var start = new Date();
db.books.find({ number: 65871 });
var end = new Date();
print(end - start); // 無索引時較慢
db.books.ensureIndex({ number: 1 }); // 1 為升序,-1 為降序
// 再次測試,耗時大幅下降
1 升序、-1 降序,複合索引順序決定排序效能。scanAndOrder)。db.books.ensureIndex({ name: -1 }, { name: "bookname" });
// 建立唯一索引
db.books.ensureIndex({ name: -1 }, { unique: true });
// 若資料已有重複值,加上 dropDups:true 會自動刪除重複文件(僅保留第一筆)
db.books.ensureIndex({ name: -1 }, { unique: true, dropDups: true });
db.books.find({ name: "1book", number: 1 }).hint({ name: -1 });
db.books.find({ name: "1book" }).explain();
// 關鍵輸出:
// "cursor" : "BtreeCursor name_1" -> 使用索引
// "nscanned" : 1 -> 掃描文件數
// "millis" : 0 -> 查詢耗時(ms)
db.system.indexes.find()db.books.ensureIndex({ number: 1 }, { background: true }) 避免鎖表影響線上服務。db.runCommand({ dropIndexes: "books", index: "name_1" })db.runCommand({ dropIndexes: "books", index: "*" })支援地理座標的鄰近、矩形、圓形範圍查詢。
// 建立 2d 索引,指定座標範圍
db.map.ensureIndex({ "gis": "2d" }, { min: -1, max: 201 });
// 1. 最近的 3 個點
db.map.find({ "gis": { $near: [70, 180] } }, { gis: 1, _id: 0 }).limit(3);
// 2. 矩形範圍查詢
var box = [[50, 50], [190, 190]];
db.map.find({ "gis": { $within: { $box: box } } }, { gis: 1, _id: 0 });
// 3. 圓形範圍查詢
var center = [55, 80], radius = 50;
db.map.find({ "gis": { $within: { $center: [center, radius] } } });
索引是 MongoDB 效能調校的核心。善用 explain() 分析查詢計畫,依據存取模式建立複合索引,並定期檢視 db.system.indexes 移除冗餘索引,即能維持最佳讀寫平衡。