淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

前言

索引是特殊的數(shù)據(jù)結(jié)構(gòu),索引存儲在一個易于遍歷讀取的數(shù)據(jù)集合中( 索引存儲在特定字段或字段集的值),而且是使用了B-tree結(jié)構(gòu)。索引可以極大程度提升MongoDB查詢效率。

如果沒有索引,MongoDB必須執(zhí)行全集合collections掃描,即掃描集合中的每個文檔,選取符合查詢條件的文檔document。 如果查詢時存在適當(dāng)?shù)乃饕?,MongoDB可以使用索引來限制它必須查詢的文檔document的數(shù)量,特別是在處理大量數(shù)據(jù)時,所以選擇正確的索引是很關(guān)鍵的、重要的。Java交流學(xué)習(xí)交流圈子

創(chuàng)建索引,需要考慮的問題:

  • 每個索引至少需要數(shù)據(jù)空間為8kb;
  • 添加索引會對寫入操作會產(chǎn)生一些性能影響。 對于具有高寫入率的集合Collections,索引很昂貴,因為每個插入也必須更新任何索引;
  • 索引對于具有高讀取率的集合Collections很有利,不會影響沒索引查詢;
  • 處于索引處于action狀態(tài)時,每個索引都會占用磁盤空間和內(nèi)存,因此需要對這種情況進行跟蹤檢測。

索引限制:

  • 索引名稱長度不能超過128字段;
  • 復(fù)合索引不能超過32個屬性;
  • 每個集合Collection不能超過64個索引;
  • 不同類型索引還具有各自的限制條件。

1. 索引管理

1.1 索引創(chuàng)建

索引創(chuàng)建使用createIndex()方法,格式如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

createIndex() 接收可選參數(shù),可選參數(shù)列表如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題
淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

1.2 查看索引

查看Collection中所有索引,格式如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

1.3 刪除索引

刪除Collection中的索引:格式如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

1.4 索引名稱

索引的默認名稱是索引鍵和索引中每個鍵的value1或-1,形式index_name+1/-1,比如:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

也可以指定索引名稱:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

1.5 查看索引創(chuàng)建過程以及終止索引創(chuàng)建

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

1.6 索引使用情況

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

1.7 MongoDB度量標(biāo)準(zhǔn)

MongoDB提供了許多索引使用和操作的度量標(biāo)準(zhǔn),在分析數(shù)據(jù)庫的索引使用時可能需要考慮這些度量標(biāo)準(zhǔn),如下所示:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

1.8 后臺索引操作

在密集(快達到數(shù)據(jù)庫最大容量)Collection創(chuàng)建索引:在默認情況下,在密集的Collection(快達到數(shù)據(jù)庫最大容量)時創(chuàng)建索引,會阻止其他操作。在給密集的Collection(快達到數(shù)據(jù)庫最大容量)創(chuàng)建索引時, 索引構(gòu)建完成之前,保存Collection的數(shù)據(jù)庫不可用于讀取或?qū)懭氩僮鳌?任何需要對所有數(shù)據(jù)庫(例如listDatabases)進行讀或?qū)戞i定的操作都將等待不是后臺進程的索引構(gòu)建完成。

因此可以使用background屬性進行設(shè)置后臺索引創(chuàng)建,操作如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

2. 索引類型

2.1 單字段索引(Single Field Indexes)

MongoDB可以在任何一個字段中創(chuàng)建索引,默認情況下,所有的集合(collections)會在_id字段中創(chuàng)建索引。_id索引是為防止客戶端插入具有相同value的_id字段的文檔Document,而且不能刪除_id字段索引。

在分片群集中使用_id索引,如果不使用_id字段作為分片鍵,則應(yīng)用程序必須確保_id字段中值的唯一性以防止出錯,解決方法為使用標(biāo)準(zhǔn)的自動生成的ObjectId來完成。

一般單字段索引的value中,“1”指定按升序?qū)椖窟M行排序的索引,“-1”指定按降序?qū)椖窟M行排序的索引。如下所示:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

在單個字段創(chuàng)建索引,示例如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

在嵌入式文檔Document中的字段創(chuàng)建索引,示例如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

在嵌入式文檔Document創(chuàng)建索引,示例如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

2.2 復(fù)合索引(Compound Index)

復(fù)合索引指的是將多個key組合到一起創(chuàng)建索引,這樣可以加速匹配多個鍵的查詢。特性如下:

  • MongoDB對任何復(fù)合索引都限制了32個字段;
  • 無法創(chuàng)建具有散列索引(hash index)類型的復(fù)合索引。如果嘗試創(chuàng)建包含散列索引字段的復(fù)合索引,則會報錯;
  • 復(fù)合索引創(chuàng)建字段索引的順序是很重要的。因為索引以升序(1)或降序(-1)排序順序存儲對字段的引用; 對于單字段索引,鍵的排序順序無關(guān)緊要,因為MongoDB可以在任一方向上遍歷索引。 但是,對于復(fù)合索引,排序順序可以決定索引是否可以支持排序操作;
  • 除了支持在所有索引字段上匹配的查詢之外,復(fù)合索引還可以支持與索引字段的前綴匹配的查詢。

創(chuàng)建復(fù)合索引的格式:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

排序順序,兩個字段的復(fù)合索引示例,index{userid:1,score:-1},先userid的value排序,然后再userid排序基礎(chǔ)下進行score排序。如下圖:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題
淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

創(chuàng)建復(fù)合索引,示例如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

復(fù)合索引中的前綴查詢,示例如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

2.3 多鍵索引

MongoDB使用多鍵索引為數(shù)組的每個元素都創(chuàng)建索引,多鍵索引可以建立在字符串、數(shù)字等key或者內(nèi)嵌文檔(document)的數(shù)組上,如果索引字段包含數(shù)組值,MongoDB會自動確定是否創(chuàng)建多鍵索引; 您不需要手動指定多鍵類型。 其中創(chuàng)建方式:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

索引邊界

使用多鍵索引,會出現(xiàn)索引邊界(索引邊界即是查詢過程中索引能查找的范圍)的計算,并計算必須遵循一些規(guī)則。即當(dāng)多個查詢的條件中字段都存在索引中時,MongoDB將會使用交集或者并集等來判斷這些條件索引字段的邊界最終產(chǎn)生一個最小的查找范圍??梢苑智闆r:

1).交集邊界

交集邊界即為多個邊界的邏輯交集,對于給定的數(shù)組字段,假定一個查詢使用了數(shù)組的多個條件字段并且可以使用多鍵索引。如果使用了$elemMatch連接了條件字段,則MongoDB將會相交多鍵索引邊界,示例如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

查詢條件分別為大于等于3、小于等于6,其中 (1)中使用了elemMatch連接查詢條件,會產(chǎn)生一個交集ratings:[[3,6]。在(2)查詢中,沒使用elemMatch,則不會產(chǎn)生交集,只要滿足任何一個條件即可。

2).并集邊界

并集邊界常常用在確定多鍵組合索引的邊界,例如:給定的組合索引{a:1,b:1},在字段a上有一個邊界:[3,+∞),在字段b上有一個邊界:(-∞,6],相并這兩個邊界的結(jié)果是:{ a: [ [ 3, Infinity ] ], b: [ [ -Infinity, 6 ] ] }。

而且如果MongoDB沒法并集這兩個邊界,MongoDB將會強制使用索引的第一個字段的邊界來進行索引掃描,在這種情況下就是: a: [ [ 3, Infinity ] ]。

3)、數(shù)組字段的組合索引

一個組合索引的索引字段是數(shù)組,例如一個survey collection集合document文檔中含有item字段和ratings數(shù)組字段,示例如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

分別處理查詢條件:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

MongoDB使用并集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

4).內(nèi)嵌文檔document的數(shù)組上建立組合索引

如果數(shù)組中包含內(nèi)嵌文檔document,想在包含的內(nèi)嵌文檔document字段上建立索引,需要在索引聲明中使用逗號“,” 來分隔字段名,示例如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

則score字段名稱就是:ratings.score。

5).混合不是數(shù)組類型的字段和數(shù)組類型字段的并集

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

MongoDB可以組合 item鍵的邊界與 ratings.score和ratings.by兩個邊界中的一個,到底是score還是by索引邊界這取決于查詢條件和索引鍵的值。MongoDB不能確保哪個邊界和item字段進行并集。 但如果想組合ratings.score和ratings.by邊界,則查詢必須使用$elemMatch。Java交流學(xué)習(xí)交流圈子

6).數(shù)組字段索引的并集邊界

在數(shù)組內(nèi)部并集索引鍵的邊界,

  • 除了字段名稱外,索引鍵必須有相同的字段路徑,
  • 查詢的時候必須在路徑上使用$elemMatch進行聲明
  • 對于內(nèi)嵌的文檔,使用逗號分隔的路徑,比如a.b.c.d是字段d的路徑。為了在相同的數(shù)組上并集索引鍵的邊界,需要$elemMatch必須使用在a.b.c的路徑上。

比如:在ratings.score和ratings.by字段上創(chuàng)建組合索引:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

字段ratings.score和ratings.by擁有共同的路徑ratings。下面的查詢使用$elemMatch則要求ratings字段必須包含一個元素匹配這兩個條件:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

分別對查詢條件進行處理:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

MongoDB可以使用并集邊界來組合這兩個邊界:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

7). 還有不使用elemMatch進行查詢以及不完整的路徑上使用elemMatch,想要了解更多可以查看《官方文檔-Multikey Index Bounds》。

限制:

  • 對于一個組合多鍵索引,每個索引文檔最多只能有一個索引字段的值是數(shù)組。如果組合多鍵索引已經(jīng)存在了,不能在插入文檔的時候違反這個限制;
  • 不能聲明一個多鍵索引作為分片鍵索引;
  • 哈希索引不能擁有多鍵索引;
  • 多鍵索引不能進行覆蓋查詢;
  • 當(dāng)一個查詢聲明把數(shù)組整體作為精確匹配的時候,MongoDB可以使用多鍵索引來查找這個查詢數(shù)組的第一個元素,但是不能使用多鍵索引掃描來找出整個數(shù)組。代替方案是當(dāng)使用多鍵索引查詢出數(shù)組的第一個元素之后,MongoDB再對過濾之后的文檔再進行一次數(shù)組匹配。

2.4 全文索引(text index)

MongoDB提供了一種全文索引類型,支持在Collection中搜索字符串內(nèi)容,對字符串與字符串?dāng)?shù)組創(chuàng)建全文可搜索的索引 。 這些全文索引不存儲特定于語言的停用詞(例如“the”,“a”,“或”),并且阻止document集合中的單詞僅存儲根詞。創(chuàng)建方式如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

而且MongoDB提供權(quán)重以及通配符的創(chuàng)建方式。查詢方式多個字符串空格隔開,排除查詢使用“-”如下所示:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

要刪除全本索引,需要將索引的名稱傳遞給db.collection.dropIndex()方法, 而要獲取索引的名稱,使用db.collection.getIndexes()方法。

還可以指定全文索引的語言,通過default_language屬性 在創(chuàng)建時指定, 或者使用language_override屬性 覆蓋掉創(chuàng)建document文檔時默認的語言,如下所示:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

權(quán)重

每個全文索引可以通過設(shè)置權(quán)重來分配不同的搜索程度,默認權(quán)重為1,對于文檔中的每個索引字段,MongoDB將匹配數(shù)乘以權(quán)重并將結(jié)果相加。 使用此總和,MongoDB然后計算文檔的分數(shù),示例如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

content權(quán)重為10,keywords為5,about為默認權(quán)重1,因此可以得出content對于keywords查詢頻率高于2倍,而對于about字段則是10倍。

通配符全文索引

在多個字段上創(chuàng)建全文索引時,還可以使用通配符說明符($**)。 使用通配符全文索引,MongoDB會為包含Collection中每個Document的字符串?dāng)?shù)據(jù)。例如:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

通配符全本索引是多個字段上的全本索引。 因此,可以在創(chuàng)建索引期間為特定字段指定權(quán)重,以控制結(jié)果的排名。

限制

  • 每個Collection一個全文索引:一個collection最多只有一個全文索引,
  • Text Search 和Hints函數(shù),如果查詢包含$ text查詢表達式,則不能使用hint();
  • Text Index and Sort,排序操作無法從文本索引獲取排序順序,即使是復(fù)合文本索引也是如此; 即排序操作不能使用文本索引中的排序;
  • 復(fù)合索引:復(fù)合索引可以包括文本索引鍵與升序/降序索引鍵的組合。 但是,這些復(fù)合索引具有以下限制:
  • 1).復(fù)合文本索引不能包含任何其他特殊索引類型,例如多鍵或地理空間索引字段。
  • 2).如果復(fù)合文本索引包括文本索引鍵之前的鍵,則執(zhí)行$ text搜索時,查詢謂詞必須包含前面鍵上的相等匹配條件。
  • 3).創(chuàng)建復(fù)合文本索引時,必須在索引規(guī)范文檔中相鄰地列出所有文本索引鍵。

2.5 Hash 索引

散列索引使用散列函數(shù)來計算索引字段值的散列值。 散列函數(shù)會折疊嵌入的文檔并計算整個值的散列值,但不支持多鍵(即數(shù)組)索引。 生成hash索引key使用了convertShardKeyToHashed()方法。創(chuàng)建方式如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

而且散列索引支持使用散列分片鍵進行分片。 基于散列的分片使用字段的散列索引作為分片鍵來分割整個分片群集中的數(shù)據(jù)。

3. 索引屬性

索引屬性有TTL索引、惟一性索引、部分索引、稀疏索引以及區(qū)分大小寫索引。

3.1 TTL索引(TTL Indexes)

TTL索引是特殊的單字段索引,并且字段類型必須是date類型或者包含有date類型的數(shù)組,MongoDB可以使用它在一定時間后或在特定時鐘時間自動從集合中刪除文檔。 數(shù)據(jù)到期對于某些類型的信息非常有用,例如機器生成的事件數(shù)據(jù),日志和會話信息,這些信息只需要在數(shù)據(jù)庫中持續(xù)有限的時間。Java交流學(xué)習(xí)交流圈子

創(chuàng)建TTL索引方法,和普通索引的創(chuàng)建方法一樣,只是會多加一個expireAfterSeconds的屬性,格式如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

例子:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

指定過期時間

首先在保存BSON日期類型值或BSON日期類型對象數(shù)組的字段上創(chuàng)建TTL索引,并指定expireAfterSeconds值為0.對于集合中的每個文檔,設(shè)置 索引日期字段為與文檔到期時間對應(yīng)的值。示例操作如下:

第一步:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

第二步:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

數(shù)據(jù)過期類型:

  • 當(dāng)指定時間到了過期的閾值數(shù)據(jù)就會過期并刪除;
  • 如果字段是數(shù)組,并且索引中有多個日期值,MongoDB使用數(shù)組中最低(即最早)的日期值來計算到期閾值;
  • 如果文檔(document)中的索引字段不是日期或包含日期值的數(shù)組,則文檔(document)將不會過期;
  • 如果文檔(document)不包含索引字段,則文檔(document)不會過期。

TTL索引特有限制:

  • TTL索引是單字段索引。 復(fù)合索引不支持TTL并忽略expireAfterSeconds選項;
  • _id屬性不支持TTL索引;
  • 無法在上限集合上創(chuàng)建TTL索引,因為MongoDB無法從上限集合中刪除文檔;
  • 不能使用createIndex()方法來更改現(xiàn)有索引的expireAfterSeconds值。而是將collMod數(shù)據(jù)庫命令與索引集合標(biāo)志結(jié)合使用。 否則,要更改現(xiàn)有索引的選項的值,必須先刪除索引并重新創(chuàng)建;
  • 如果字段已存在非TTL單字段索引,則無法在同一字段上創(chuàng)建TTL索引,因為無法在相同key創(chuàng)建不同類型的的索引。 要將非TTL單字段索引更改為TTL索引,必須先刪除索引并使用expireAfterSeconds選項重新創(chuàng)建。

3.2 惟一性索引(Unique Indexes)

唯一索引可確保索引字段不存儲重復(fù)值; 即強制索引字段的唯一性。 默認情況下,MongoDB在創(chuàng)建集合期間在_id字段上創(chuàng)建唯一索引。創(chuàng)建方式如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

單個字段創(chuàng)建方式,示例如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

唯一性復(fù)合索引: 還可以對復(fù)合索引強制執(zhí)行唯一約束。 如果對復(fù)合索引使用唯一約束,則MongoDB將對索引鍵值的組合強制實施唯一性。示例如下

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

唯一多鍵索引:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

創(chuàng)建唯一索引到副本或者分片中: 對于副本集和分片集群,使用滾動過程創(chuàng)建唯一索引需要在過程中停止對集合的所有寫入。 如果在過程中無法停止對集合的所有寫入,請不要使用滾動過程。 相反,通過以下方式在集合上構(gòu)建唯一索引:

  • 在主服務(wù)器上為副本集發(fā)出db.collection.createIndex()
  • 在mongos上為分片群集發(fā)出db.collection.createIndex()

NOTE:詳細解析可以看

限制:

  • 如果集合已經(jīng)包含超出索引的唯一約束的數(shù)據(jù)(即有重復(fù)數(shù)據(jù)),則MongoDB無法在指定的索引字段上創(chuàng)建唯一索引。
  • 不能在hash索引上創(chuàng)建唯一索引
  • 唯一約束適用于Collection中的一個Document。由于約束適用于單文檔document,因此對于唯一的多鍵索引,只要該文檔document的索引鍵值不與另一個文檔document的索引鍵值重復(fù),文檔就可能具有導(dǎo)致重復(fù)索引鍵值的數(shù)組元素。 在這種情況下,重復(fù)索引記錄僅插入索引一次。
  • 分片Collection唯一索引只能如下:
  • 1).分片鍵上的索引
  • 2).分片鍵是前綴的復(fù)合索引
  • 3).默認的_id索引; 但是,如果_id字段不是分片鍵或分片鍵的前綴,則_id索引僅對每個分片強制執(zhí)行唯一性約束。如果_id字段不是分片鍵,也不是分片鍵的前綴,MongoDB希望應(yīng)用程序在分片中強制執(zhí)行_id值的唯一性。

3.3 部分索引(Partial Indexes)

部分索引通過指定的過濾表達式去達到局部搜索。通過db.collection.createIndex()方法中增加partialFilterExpression屬性創(chuàng)建,過濾表達式如下:

  • 等式表達式(即 file:value或使用$eq運算符)
  • $exists表達式
  • gt,gte,lt,lte 表達式
  • $type表達式
  • $and

示例如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

其中:

  • (1)查詢: 查詢條件{ gte: 8 }于創(chuàng)建索引條件{gt: 5 }可以構(gòu)成一個完整集(查詢條件是創(chuàng)建索引條件的子集,即大于5可以包含大于等于 8),可以使用部分索引查詢。
  • (2)查詢: 條件達不到完整集,MongoDB將不會將部分索引用于查詢或排序操作。
  • (3)查詢: 次查詢沒有使用過濾表達式,也不會使用部分索引,因為要使用部分索引,查詢必須包含過濾器表達式(或指定過濾器表達式子集的已修改過濾器表達式)作為其查詢條件的一部分Java交流學(xué)習(xí)交流圈子

限制:

  • 不可以僅通過過濾表達式創(chuàng)建多個局部索引;
  • 不可以同時使用局部索引和稀疏索引(sparse index);
  • _id索引不能使用局部索引,分片索引(shard key index)也不能使用局部索引;
  • 同時指定partialFilterExpression和唯一約束,則唯一約束僅適用于滿足過濾器表達式的文檔。 如果Document不符合篩選條件,則具有唯一約束的部分索引是允許插入不符合唯一約束的Document。

3.4 稀疏索引(Sparse Indexes)

稀疏索只引搜索包含有索引字段的文檔的條目,跳過索引鍵不存在的文檔,即稀疏索引不會搜索不包含稀疏索引的文檔。默認情況下, 2dsphere (version 2), 2d, geoHaystack, 全文索引等總是稀疏索引。創(chuàng)建方式db.collection.createIndex()方法增加sparse屬性,如下所示:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

稀疏索引不被使用的情況: 如果稀疏索引會導(dǎo)致查詢和排序操作的結(jié)果集不完整,MongoDB將不會使用該索引,除非hint()示顯式指定索引。

稀疏復(fù)合索引:

  • 對于包含上升/下降排序的稀疏復(fù)合索引,只要復(fù)合索引中的一個key 索引存在都會被檢測出來
  • 對于包含上升/下降排序的包含地理空間可以的稀疏復(fù)合索引,只有存在地理空間key才能被檢測出來
  • 對于包含上升/下降排序的全文索引的稀疏復(fù)合索引,只有存在全文索引索引才可以被檢測

稀疏索引與唯一性: 一個既包含稀疏又包含唯一的索引避免集合上存在一些重復(fù)值得文檔,但是允許多個文檔忽略該鍵。滿足稀疏索引和唯一性操作其兩個限制都要遵循。

整合示例如下:

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

其中:

  • (1)查詢: 可以使用稀疏索引查詢,返回完整集:{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
  • (2)查詢: 即使排序是通過索引字段進行的,MongoDB也不會選擇稀疏索引來完成查詢以返回完整的結(jié)果:
  • { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
  • { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
  • { "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
  • (3)查詢: 使用hint()返回所需完整集:
  • { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
  • { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

4. 其他事項

4.1 索引策略

索引策略:

  • 應(yīng)用程序的最佳索引必須考慮許多因素,包括期望查詢的類型,讀取與寫入的比率以及系統(tǒng)上的可用內(nèi)存量。
  • 在開發(fā)索引策略時,您應(yīng)該深入了解應(yīng)用程序的查詢。在構(gòu)建索引之前,映射將要運行的查詢類型,以便您可以構(gòu)建引用這些字段的索引。索引具有性能成本,但是對于大型數(shù)據(jù)集上的頻繁查詢而言,它們的價值更高??紤]應(yīng)用程序中每個查詢的相對頻率以及查詢是否證明索引是合理的。
  • 設(shè)計索引的最佳總體策略是使用與您將在生產(chǎn)中運行的數(shù)據(jù)集類似的數(shù)據(jù)集來分析各種索引配置,以查看哪些配置性能最佳。檢查為集合創(chuàng)建的當(dāng)前索引,以確保它們支持您當(dāng)前和計劃的查詢。如果不再使用索引,請刪除索引。
  • 通常,MongoDB僅使用一個索引來完成大多數(shù)查詢。但是,$或查詢的每個子句可能使用不同的索引,從2.6開始,MongoDB可以使用多個索引的交集。

粉絲福利

淺入淺出MongonDB,教你輕松應(yīng)對面試中遇到的MongonDB索引問題

推薦一個Java交流學(xué)習(xí)交流圈子 里面會分享一些資深架構(gòu)師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務(wù)架構(gòu)的原理,JVM性能優(yōu)化這些成為架構(gòu)師必備的知識體系。還能領(lǐng)取免費的學(xué)習(xí)資源,目前受益良多

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 這是一篇僅用于自身練習(xí)翻譯的文章以及記錄對mongodb相關(guān)的一些理解,如有錯誤歡迎指正。 嗯。谷歌機翻真的差的要...
    差很多先生CL閱讀 813評論 0 5
  • 一、 索引類型 (一)、單鍵索引 在一個鍵上創(chuàng)建的索引就是單鍵索引,單鍵索引是最常見的索引,如MongoDB默認創(chuàng)...
    louisliaoxh閱讀 979評論 0 0
  • MongoDB提供了許多不同的方法,可以在其中形成索引并將其存儲在內(nèi)存(和磁盤)中。 這些索引中的每一個都有不同的...
    我是一名搬運工閱讀 515評論 0 1
  • 本文包括以下幾個方面: –安全措施 – 部署架構(gòu) – 系統(tǒng)優(yōu)化 – 索引設(shè)計 – 備份監(jiān)控 – 模式設(shè)計 – 程序...
    張偉科閱讀 4,014評論 0 9
  • 寫在前面:以前總是覺得自我總結(jié)是寫給自己看的,會寫在自己的小日記本上,會寫在電腦的隱藏word文檔中,但是現(xiàn)在想想...
    吃不胖的團子閱讀 265評論 0 0