MongoDB索引

前言

在MongoDB中,索引通常能夠極大的提高查詢的效率。如果沒有索引,MongoDB在讀取數據時必須掃描集合中的每個文檔并選取那些符合查詢條件的記錄。如果有一個合適的索引來進行查詢,則可以限制掃描文檔的數量。
  索引是特殊的數據結構,存儲在一個易于遍歷讀取的數據集合中,它是對數據庫表中一列或多列的值進行排序的一種結構。索引條目的排序支持高效的匹配和基于范圍的查詢操作,同時,MongoDB可以通過使用索引返回排序后的結果。
  下面的示意圖表明如何通過索引篩選和整理匹配的文檔。($lt條件操作符表示小于,{score:-1或者1}表示逆向排序或者正向排序)

index-for-sort.png

  從本質上來說,MongoDB中的索引與其他數據庫系統中的索引相類似,對于集合中的任何域或者子域都支持索引。

默認索引 _id

MongoDB在創建集合時,會在_id域創建一個唯一性的索引,即禁止插入兩個具有相同_id值的文檔,同時該索引無法被刪除。

查詢、創建、刪除索引

//查詢索引
db.集合名.getIndexes()
//創建索引
db. 集合名.createIndex( <key and index type specification>, <options> )
//刪除索引
db.集合名.dropIndex(<key and index type specification>)

常見索引

  • 單鍵索引
    MongoDB支持用戶對文檔的一個域創建單鍵索引,進行操作時,排列順序并不重要因為無論升序還是降序,MongoDB均能做遍歷。
    假設有名為records的集合,其中有一個記錄如下:
{ 
"_id": ObjectId("570c04a4ad233577f97dc459"), 
"userid": 1,
"score": 1034, 
"location": { state: "NY", city: "New York" }
}

創建單鍵索引舉例:

//這里的1不是值,而是代表排序方向,即升序
db.records.createIndex( { score: 1 } )
index-ascending
  • 復合索引
    當查詢條件不止一個時,即要查詢的字段不止一個時,就需要創建復合索引,最大字段數為31。
    創建復合索引舉例(排列原則為,先對userid進行排序,在userid相同的基礎上,再對score進行排序):
db.collection.createIndex( {userid:1, score:-1} )
// 查詢時,支持對多個字段查詢,也支持對單個字段查詢
db.collection.find( { userid: "aa1" } )
db.collection.find( { userid: "ca2", score: { $gt: 60} } )

index-compound-key

1)排序順序:
假設一個集合events的文檔有兩個字段usernamedate,使用下面兩條不同的語句查詢:

db.events.find().sort( { username: 1, date: -1 } )
db.events.find().sort( { username: -1, date: 1 } )

可支持上面兩條查詢語句的索引為:

db.events.createIndex( { "username" : 1, "date" : -1 } )

但是,該索引卻不支持下面的查詢:

db.events.find().sort( { username: 1, date: 1 } )

更多詳情可參考 Use Indexes to Sort Query Results(需翻墻)
2)前綴:
索引前綴是復合索引字段的子集。例如,考慮下面的復合:
{ "item": 1, "location": 1, "stock": 1 }
它的索引前綴為:

{ item: 1 }
{ item: 1, location: 1 }

該復合索引可查詢的方法有如下幾種:

the item field,
the item field and the location field,
the item field and the location field and the stock field.

當然還有the item field and the stock field,因為item field是一個索引前綴,當然這樣的效率不及直接用item field and the stock field作為一個復合索引。
但是,下面的查詢方法是不支持的,因為缺少了item字段而不符合索引前綴。

the location field,
the stock field,
the location and stock fields.

如果建立了復合索引,同時有一個單鍵索引與它的復合索引重復,當它們沒有稀疏或者唯一的屬性時,可把單鍵索引刪去。因為MongoDB會在能使用復合索引前綴的任何情況下優先用之。

  • 多鍵索引
    多鍵索引和單鍵索引創建形式相同,區別在于字段的值。對于單鍵索引,字段的值為一個單一的值,如字符串,數字,日期。對于多鍵索引,值具有多個記錄,如數組。為了給一個數組字段創建索引,MongoDB為數組中的每一個元素均創建一個索引鍵。多鍵索引支持高效查詢數組字段,它可以被構建在包含字符串、數字類型或者嵌套文檔的數組。
    創建多鍵索引舉例:
db.collection.createIndex( { addr.zip: 1 } )

index-multikey

1)限制
多鍵索引不支持以下幾種情況:分片鍵、哈希索引、覆蓋查詢。
對于復合多鍵索引,多個字段不能同時為數組,但允許其中一個字段為數組。
MongoDB無法直接使用整個數組作為查詢條件,而是將數組的第一個元素作為查詢條件,得到符合第一個元素的文檔,返回給MongoDB,再使用第二個元素作為查詢條件,直到得到最終結果。

  • 過期索引
    顧名思義,即在一段時間后便會過期的索引,在索引過期后,相應的數據會被刪除。適合存儲在一段時間之后會失效的數據比如用戶的登錄信息、存儲的日志。
    創建過期索引舉例(expireAfterSeconds后的值表示多少秒后刪除):
db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )

參考英文文檔,由于英文水平不足,有些部分翻譯會比較生硬。
如有建議,歡迎指出。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容

  • 索引能夠提高數據庫的查詢效率,沒有索引的話,查詢會進行全表掃描(scan every document in...
    zhglance閱讀 2,047評論 0 6
  • 索引是數據庫中的一個重要對象,主要用于支持高效查詢操作。如果沒有索引,數據庫就只能進行全表掃描,效率將極為低下。m...
    UncleYee閱讀 2,456評論 0 5
  • Mongodb索引及查詢優化分析 創建索引 參數說明:keys: {FieldNameOne:ascending,...
    liudongdong閱讀 4,322評論 1 8
  • 1、_id索引: 自動創建 2、單鍵索引: 【值為一個單個的值,例如字符串、數字或者日期】db.nums.in...
    Uzero閱讀 786評論 2 0
  • MongoDB在創建集合的時候就在_id字段創建了一個唯一性索引. 這個索引防止客戶端插入兩個擁有相同_id的文檔...
    Eve0閱讀 417評論 0 0