MongoDB索引问题
索引類型:
MongoDB有多種索引類型,每種索引類型有其適合的場景。
對于單字段索引而言,升序和降序效果是一樣的。
復(fù)合索引針對多個字段聯(lián)合創(chuàng)建索引,先按第一個字段排序,第一個字段相同的文檔按第二個字段排序,以此類推。復(fù)合索引也能滿足單個字段的索引,但僅限復(fù)合索引首個字段。
當索引的字段為數(shù)組時,創(chuàng)建出的索引為多key索引,多key索引會為數(shù)組的每個元素建立一條索引,比如下圖所示BillInterceptLifeInfo表中加入一個NeedSyncSiteCodes字段,需要查詢NeedSyncSiteCodes中是否包含了某個sitecode就可以利用該字段的多key索引。
?
實際場景:
攔截件監(jiān)控代碼中,主要的數(shù)據(jù)在一個攔截件生命期表, 該表記錄了攔截件的生命期狀態(tài),一個應(yīng)下發(fā)設(shè)備表和一個實際下發(fā)設(shè)備表。
表結(jié)構(gòu)如下:
其中更新應(yīng)下發(fā)設(shè)備表是要查詢出1.站點信息相符的所有單號,且該單號的2.結(jié)束時間大于當前時間,且該3.應(yīng)下發(fā)List中不含即將插入的deviceID才會插入一條記錄。
因為需要下發(fā)的站點列表和需要下發(fā)的設(shè)備列表是兩個list,無法一起建索引,因此決定建EndTime和NeedSyncSiteCodes的復(fù)合索引,NeedSyncSiteCodes也是一個多key索引。
一開始建索引如下:
?
?db.BillInterceptLifeInfo.createIndex({? "EndTime"?:?1,?"NeedSyncSiteCodes"?:?1 })? 代碼上線后,一開始平穩(wěn),但數(shù)據(jù)量上千后開始不穩(wěn)定 后根據(jù)系統(tǒng)優(yōu)化提示將索引改為: ?db.BillInterceptLifeInfo.createIndex({?"NeedSyncSiteCodes"?:?1 ,?"EndTime"?:?1,})? 監(jiān)控如圖: 根據(jù)某兩條查詢對比來看: 前:?后: 可以看出,組合索引的先后順序不同,EndTime在前的索引Key match到的記錄有5K多條,而實際需要修改的只有3條, NeedSyncSiteCodes在前的索引Key match到的記錄有107條,而這107條都是需要修改的,NeedSyncSiteCodes在前的這條索引能縮小二次匹配的范圍程度更大。 在復(fù)合索引中,多個字段應(yīng)把最有區(qū)分度的字段放前面,比如一個person表中有一個[name + age]的復(fù)合索引,age字段的取值很有限,即擁有相同age字段的文檔會有很多;而name字段的取值則豐富很多,擁有相同name字段的文檔很少;顯然先按name字段查找,再在相同name的文檔里查找age字段更為高效。 同理,在此例子中的EndTime和NeedSyncSiteCodes兩個字段建復(fù)合索引,EndTime的區(qū)分度肯定不如NeedSyncSiteCodes的多key索引。因此將NeedSyncSiteCodes作為復(fù)合索引的第一項更高效。 復(fù)合多key索引中:- 對于一個復(fù)合多key索引,每一個索引最多可以包含一個數(shù)組。
- 在多于一個數(shù)組的情形下來創(chuàng)建復(fù)合多key索引不被支持。
?
另外談下B樹(即B-樹)和B+樹的區(qū)別,以及為什么mongodb用B-樹而不用B+樹。
首先B樹結(jié)構(gòu)(細節(jié)請自行查閱)如下圖:
每個節(jié)點存有key對應(yīng)的data, 每個節(jié)點上的n個key有n+1個子節(jié)點。
一個m階的B樹每個節(jié)點至少有m個孩子。
一棵含有N個總關(guān)鍵字數(shù)的m階的B樹的最大高度是log_ceil(m/2)(N+1)/2?+ 1。
因此B數(shù)的高度相對會下降,而高度下降,定位數(shù)據(jù)會更快。由于B數(shù)節(jié)點中存數(shù)據(jù),最快查詢可為O(1)。
?
而B+樹,如下圖:
?
B+樹的特點是,key的副本存儲在內(nèi)部節(jié)點,真正的key-data存儲在葉子節(jié)點上。
n個key的節(jié)點指針域是n而不是n+1(mongodb 是n+1)
為了增加區(qū)間訪問性,B+樹的葉子節(jié)點兩兩相連,對于范圍查詢大大增加了友好度。
?
B樹和B+樹在磁盤訪問這一點上
?
B樹和B+樹各有優(yōu)缺點,對于mongodb來說,mongdb是一種文檔型數(shù)據(jù)庫,使用json格式保存數(shù)據(jù),歸屬于聚合型數(shù)據(jù)庫。適用于數(shù)據(jù)模型簡單,性能要求高的場合。
而mysql之類的關(guān)系型數(shù)據(jù)庫,區(qū)間訪問是很常見的現(xiàn)象,B+樹支持區(qū)間訪問,因此mysql更適合用B+樹。
轉(zhuǎn)載于:https://www.cnblogs.com/sylvialucy/p/10981796.html
總結(jié)
以上是生活随笔為你收集整理的MongoDB索引问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 接口隔离原则——面向对象设计原则
- 下一篇: aria2的安装与配置