MongoDB索引

前言

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

index-for-sort.png

  從本質(zhì)上來(lái)說(shuō),MongoDB中的索引與其他數(shù)據(jù)庫(kù)系統(tǒng)中的索引相類似,對(duì)于集合中的任何域或者子域都支持索引。

默認(rèn)索引 _id

MongoDB在創(chuàng)建集合時(shí),會(huì)在_id域創(chuàng)建一個(gè)唯一性的索引,即禁止插入兩個(gè)具有相同_id值的文檔,同時(shí)該索引無(wú)法被刪除。

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

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

常見(jiàn)索引

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

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

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

index-compound-key

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

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

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

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

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

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

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

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

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

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

當(dāng)然還有the item field and the stock field,因?yàn)?code>item field是一個(gè)索引前綴,當(dāng)然這樣的效率不及直接用item field and the stock field作為一個(gè)復(fù)合索引。
但是,下面的查詢方法是不支持的,因?yàn)槿鄙倭?code>item字段而不符合索引前綴。

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

如果建立了復(fù)合索引,同時(shí)有一個(gè)單鍵索引與它的復(fù)合索引重復(fù),當(dāng)它們沒(méi)有稀疏或者唯一的屬性時(shí),可把單鍵索引刪去。因?yàn)镸ongoDB會(huì)在能使用復(fù)合索引前綴的任何情況下優(yōu)先用之。

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

index-multikey

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

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 索引能夠提高數(shù)據(jù)庫(kù)的查詢效率,沒(méi)有索引的話,查詢會(huì)進(jìn)行全表掃描(scan every document in...
    zhglance閱讀 2,108評(píng)論 0 6
  • 索引是數(shù)據(jù)庫(kù)中的一個(gè)重要對(duì)象,主要用于支持高效查詢操作。如果沒(méi)有索引,數(shù)據(jù)庫(kù)就只能進(jìn)行全表掃描,效率將極為低下。m...
    UncleYee閱讀 2,541評(píng)論 0 5
  • Mongodb索引及查詢優(yōu)化分析 創(chuàng)建索引 參數(shù)說(shuō)明:keys: {FieldNameOne:ascending,...
    liudongdong閱讀 4,404評(píng)論 1 8
  • 1、_id索引: 自動(dòng)創(chuàng)建 2、單鍵索引: 【值為一個(gè)單個(gè)的值,例如字符串、數(shù)字或者日期】db.nums.in...
    Uzero閱讀 854評(píng)論 2 0
  • MongoDB在創(chuàng)建集合的時(shí)候就在_id字段創(chuàng)建了一個(gè)唯一性索引. 這個(gè)索引防止客戶端插入兩個(gè)擁有相同_id的文檔...
    Eve0閱讀 471評(píng)論 0 0

友情鏈接更多精彩內(nèi)容