MongoDB索引

前言

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

index-for-sort.png

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

默認索引 _id

MongoDB在創(chuàng)建集合時咸这,會在_id域創(chuàng)建一個唯一性的索引夷恍,即禁止插入兩個具有相同_id值的文檔,同時該索引無法被刪除媳维。

查詢裁厅、創(chuàng)建、刪除索引

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

常見索引

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

創(chuàng)建單鍵索引舉例:

//這里的1不是值侥啤,而是代表排序方向当叭,即升序
db.records.createIndex( { score: 1 } )
index-ascending
  • 復合索引
    當查詢條件不止一個時,即要查詢的字段不止一個時盖灸,就需要創(chuàng)建復合索引蚁鳖,最大字段數為31。
    創(chuàng)建復合索引舉例(排列原則為赁炎,先對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會在能使用復合索引前綴的任何情況下優(yōu)先用之同波。

  • 多鍵索引
    多鍵索引和單鍵索引創(chuàng)建形式相同鳄梅,區(qū)別在于字段的值。對于單鍵索引未檩,字段的值為一個單一的值戴尸,如字符串,數字冤狡,日期孙蒙。對于多鍵索引,值具有多個記錄悲雳,如數組挎峦。為了給一個數組字段創(chuàng)建索引,MongoDB為數組中的每一個元素均創(chuàng)建一個索引鍵合瓢。多鍵索引支持高效查詢數組字段坦胶,它可以被構建在包含字符串、數字類型或者嵌套文檔的數組晴楔。
    創(chuàng)建多鍵索引舉例:
db.collection.createIndex( { addr.zip: 1 } )

index-multikey

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

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

參考英文文檔旋炒,由于英文水平不足步悠,有些部分翻譯會比較生硬。
如有建議瘫镇,歡迎指出鼎兽。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市铣除,隨后出現的幾起案子谚咬,更是在濱河造成了極大的恐慌,老刑警劉巖尚粘,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件择卦,死亡現場離奇詭異,居然都是意外死亡郎嫁,警方通過查閱死者的電腦和手機秉继,發(fā)現死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泽铛,“玉大人尚辑,你說我怎么就攤上這事】唬” “怎么了杠茬?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铲觉。 經常有香客問我,道長吓坚,這世上最難降的妖魔是什么撵幽? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮礁击,結果婚禮上盐杂,老公的妹妹穿的比我還像新娘。我一直安慰自己哆窿,他們只是感情好链烈,可當我...
    茶點故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挚躯,像睡著了一般强衡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上码荔,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天漩勤,我揣著相機與錄音感挥,去河邊找鬼。 笑死越败,一個胖子當著我的面吹牛触幼,可吹牛的內容都是我干的。 我是一名探鬼主播究飞,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼置谦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了亿傅?” 一聲冷哼從身側響起媒峡,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎袱蜡,沒想到半個月后丝蹭,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡坪蚁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年奔穿,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敏晤。...
    茶點故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡贱田,死狀恐怖,靈堂內的尸體忽然破棺而出嘴脾,到底是詐尸還是另有隱情男摧,我是刑警寧澤,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布译打,位于F島的核電站耗拓,受9級特大地震影響,放射性物質發(fā)生泄漏奏司。R本人自食惡果不足惜乔询,卻給世界環(huán)境...
    茶點故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望韵洋。 院中可真熱鬧竿刁,春花似錦、人聲如沸搪缨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽副编。三九已至负甸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背惑惶。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工煮盼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人带污。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓僵控,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鱼冀。 傳聞我的和親對象是個殘疾皇子报破,可洞房花燭夜當晚...
    茶點故事閱讀 45,937評論 2 361

推薦閱讀更多精彩內容

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