MongoDB索引類型:單字段、複合索引怎麼建?

什麼是MongoDB索引?

在MongoDB中,索引就像一本書的“目錄”——沒有目錄時,你得翻遍全書找內容;有了目錄,就能快速定位到目標內容。索引的核心作用是加速查詢,避免全表掃描(即遍歷整個集合),讓查詢更快更高效。

爲什麼需要建索引?

想象你有一個存了100萬條用戶數據的集合,要找“年齡=25歲”的用戶。如果沒有索引,MongoDB會逐條檢查每條數據,可能要掃描幾十萬條;但如果給age字段建了索引,MongoDB就會直接通過索引定位到所有年齡爲25歲的文檔,效率瞬間提升。

單字段索引:最簡單的索引類型

單字段索引是給單個字段建立的索引,是最基礎也最常用的索引類型。

適用場景

  • 當查詢條件只涉及一個字段(如nameage)。
  • 當需要按單個字段排序(如按reg_time降序查最新註冊用戶)。

創建語法

db.集合名.createIndex({字段名: 1})  // 1表示升序,-1表示降序

例子

假設我們有一個“學生表”集合students,經常需要查詢“年齡爲20歲的學生”,可以這樣建索引:

// 給age字段建升序索引
db.students.createIndex({age: 1})  

// 查詢時,MongoDB會自動使用age索引
db.students.find({age: 20}).explain("executionStats")  

注意

  • 升序(1)和降序(-1)的選擇取決於查詢需求。比如按年齡倒序查學生,建{age: -1}更合適。
  • 單字段索引僅能優化包含該字段的查詢。例如,給age建索引後,只有find({age: x})能用上索引,find({name: "小明"})無法使用這個索引。

複合索引:同時優化多個字段的查詢

複合索引是給多個字段組合建立的索引,適合需要同時過濾或排序多個字段的場景(如“按地區+註冊時間”查用戶)。

核心原則:左前綴原則

複合索引的順序非常關鍵!MongoDB會按照索引定義的字段順序(左到右)生效,只有包含索引最左側的字段的查詢,才能用上整個複合索引。

例子1:正確使用複合索引

假設我們建了{region: 1, reg_time: -1}的複合索引(先按地區升序,再按註冊時間降序):
- ✅ 能用索引的查詢:find({region: "北京", reg_time: {$gt: ISODate("2023-01-01")}})(先過濾地區,再過濾註冊時間)。
- ❌ 不能用索引的查詢:find({reg_time: {$gt: ISODate("2023-01-01")}})(缺少最左側字段region,無法觸發左前綴原則)。

例子2:順序反了會怎樣?

如果建了{reg_time: -1, region: 1}的複合索引(先按註冊時間降序,再按地區升序):
- ✅ 能用索引的查詢:find({reg_time: {$gt: ISODate("2023-01-01")}})(僅用reg_time)或find({reg_time: {$gt: ISODate("2023-01-01"), region: "北京"}})
- ❌ 無法用索引的查詢:find({region: "北京"})(缺少最左側字段reg_time)。

創建語法

db.集合名.createIndex({字段1: 1, 字段2: -1})  // 逗號分隔,1升序,-1降序

例子:電商訂單查詢

假設我們有orders集合,經常需要查詢“地區=上海+訂單狀態=已支付”的訂單,且按“下單時間”降序排序。此時可以建複合索引:

db.orders.createIndex({region: 1, status: 1, order_time: -1})  

這個索引能同時優化:
- 過濾條件:region: "上海"(最左側字段)、status: "已支付"(第二個字段)。
- 排序條件:order_time: -1(第三個字段,降序)。

索引的“坑”:別讓索引變成負擔

索引不是越多越好,過度索引會影響寫入性能(插入、更新、刪除時需維護索引)。需要注意:

  1. 避免重複索引:比如給同一個字段建多個索引(如{age:1}{age:-1}),只會浪費空間且無法同時生效。
  2. 低選擇性字段少建索引:如果字段值重複率高(如“性別”只有男/女),建索引效果有限,甚至不如全表掃描。
  3. 只對高頻查詢建索引:比如每天查詢100次的字段值得建索引,偶爾查詢的字段沒必要。

總結

  • 單字段索引:適合單字段過濾/排序,語法簡單,是基礎。
  • 複合索引:適合多字段過濾+排序,核心是左前綴原則(僅用最左側字段的查詢能觸發索引)。
  • 關鍵原則:索引要“按需建、適度建”,用在高頻查詢場景,避免影響寫入效率。

如果數據量大且查詢複雜,複合索引能顯著提升性能;但記住:索引是爲了加速查詢,不是“萬能藥”,合理規劃才能讓MongoDB跑得更快~

小夜