新聞中心
數(shù)據(jù)庫的索引與書籍的索引/目錄類似,有了索引就不需要翻整本書,數(shù)據(jù)庫可以直接在索引中查找,在索引中找到條目之后,就可以直接跳轉(zhuǎn)到目標(biāo)文檔的位置,這就能使查找速度提高幾個(gè)數(shù)量級(jí)。不使用索引的查詢稱為全表掃描,也就是說服務(wù)器必須查找完一整本書才能找到查詢結(jié)果,對(duì)于大集合來說,應(yīng)該盡量避免全表掃描,否則效率非常低。建立索引是保證數(shù)據(jù)庫性能、保證小程序體驗(yàn)的重要手段。我們應(yīng)為所有需要成為查詢條件的字段建立索引。

一、 索引的類型與管理
我們可以在云開發(fā)控制臺(tái)數(shù)據(jù)庫標(biāo)簽頁對(duì)每個(gè)集合的字段添加索引,設(shè)置索引的屬性為唯一或非唯一,排序方式為升序或降序,也能查看該索引所占的空間和命中次數(shù)。索引是一個(gè)文件,它是要占據(jù)物理空間的,因此我們可以留意不要過度索引浪費(fèi)空間,而命中次數(shù)也可以用于判斷索引是否有效。
1、_id索引和_openid索引
云開發(fā)數(shù)據(jù)庫會(huì)給每個(gè)集合默認(rèn)建立_id索引和_openid索引。_id索引在我們進(jìn)行db.collection('集合名').doc("_id值")的請(qǐng)求時(shí)就會(huì)命中。而當(dāng)我們?cè)趙here里添加_openid為查詢條件,就會(huì)命中_openid索引,在小程序端進(jìn)行db.collection('集合名')查詢時(shí),由于自帶默認(rèn)條件_openid為用戶的openid,因此在小程序端查詢都會(huì)命中_openid索引。
2、單字段索引
單字段索引是最常見的索引,它不會(huì)自動(dòng)創(chuàng)建。對(duì)需要作為查詢條件篩選的字段,我們可以創(chuàng)建單字段索引。如果需要對(duì)嵌套字段進(jìn)行索引,那么可以通過 "點(diǎn)表示法" 用點(diǎn)連接起嵌套字段的名稱。比如我們需要對(duì)如下格式的記錄中的 color 字段進(jìn)行索引時(shí),可以用 style.color 表示。在設(shè)置單字段索引時(shí),指定排序?yàn)樯蚧蚪敌蚨伎梢?,?/p>
{
"_id": '',
"style": {
"color": ''
}
}
3、組合索引
組合索引即一個(gè)索引包含多個(gè)字段,組合索引在添加時(shí)要注意字段的順序,順序不同索引的效果也會(huì)不同。當(dāng)查詢條件使用的字段包含在索引定義的所有字段或前綴字段里時(shí),會(huì)命中索引。
組合索引遵循最左前綴原則,比如在 A, B, C 三個(gè)字段定義的組合索引(A, B, C),那么查詢條件A,{A, B},{A, C},{A, B, C}索引都會(huì)有效,查詢條件B,C,{B, C}則不會(huì)命中索引。根據(jù)最左前綴原則,我們可以明白組合索引(A, B)和調(diào)換字段順序的(B, A)效果是不一樣的。當(dāng)定義組合索引為(A, B)時(shí),索引會(huì)先按 A 字段排序再按 B 字段排序。因此當(dāng)組合索引設(shè)為 (A, B) 時(shí),即使我們沒有單獨(dú)對(duì)字段 A 設(shè)立索引,但對(duì)字段 A 的查詢可以命中 (A, B) 索引。
定義索引時(shí)字段的排序方式也決定排序查詢是否有效,比如我們對(duì)字段 A 和 B 設(shè)置以下索引:(A: 升序,B: 降序),那么當(dāng)我們查詢需要對(duì) A, B 進(jìn)行排序時(shí),可以指定排序結(jié)果為 A 升序、B 降序以及完全相反的排序A 降序、B 升序有效,而A升B升,A降B降都不會(huì)命中索引。
還有一些查詢條件,需要進(jìn)行范圍查詢或者排序,那么范圍查詢和排序的字段就要盡量往后放,因?yàn)榉秶樵円院蟮淖侄嗡饕遣荒苊械?。組合索引的好處已經(jīng)在上面有提到了,如果數(shù)據(jù)庫有a索引,現(xiàn)在b列也需要索引,那么直接建立(a,b)即可
4、索引的唯一性
創(chuàng)建索引時(shí)可以指定增加唯一性限制,具有唯一性限制的索引會(huì)要求被索引集合不能存在被索引字段值都相同的兩個(gè)記錄。需特別注意的是,假如記錄中不存在某個(gè)字段,則對(duì)索引字段來說其值默認(rèn)為 null,如果索引有唯一性限制,則不允許存在兩個(gè)或以上的該字段為空 / 不存在該字段的記錄。
db.collection("china")
.where({
gdp: _.gt(3000),
city_area:_.lt(10000),
reg_pop:_.gt(6000)
})
.field({
_id:false,
city: true,
city_area: true,
gdp:true
})
.orderBy('gdp', 'desc')
.orderBy('city_area', 'asc') 由于有三個(gè)查詢條件,為你可以給三個(gè)查詢條件按照順序創(chuàng)建索引,由于這幾個(gè)值無法做到非唯一,且存在空值的可能(有些城市沒有數(shù)據(jù)),所以創(chuàng)建時(shí)選擇非唯一。
二、 索引的創(chuàng)建說明
1、索引的優(yōu)點(diǎn)和缺點(diǎn)
索引雖然能非常高效的提高查詢速度,同時(shí)卻會(huì)降低更新表的速度。實(shí)際上索引也是一張表,該表保存了主鍵與索引字段,并指向?qū)嶓w表的記錄,所以索引列也是要占用空間的。索引需要進(jìn)行兩次查找,一次是查找索引條目,一次是根據(jù)索引指針去查找相應(yīng)的文檔,而全表查詢只需要進(jìn)行一次查找。集合較大、文檔較大、選擇性查詢就比較適合用索引。
其實(shí)建索引的原理就是將磁盤I/O操作的最小化,不在磁盤中排序,而是在內(nèi)存中排好序,通過排序的規(guī)則去指定磁盤讀取就行,也不需要在磁盤上隨機(jī)讀取。
索引并非越多越好,一個(gè)表中如有大量的索引,不僅占用磁盤空間,而且會(huì)影響增刪改等語句的性能,因?yàn)楫?dāng)表中的數(shù)據(jù)更改的同時(shí),索引也會(huì)進(jìn)行調(diào)整和更新。避免對(duì)經(jīng)常更新的表設(shè)計(jì)過多的索引,并且索引中的列盡可能要少,而對(duì)經(jīng)常用于查詢的字段應(yīng)該創(chuàng)建索引,但要避免添加不必要的字段。
為了減少索引的數(shù)量,可以建立組合索引,組合索引就是可以使用多個(gè)列一起建立一個(gè)索引。建立索引時(shí)要優(yōu)先在已經(jīng)存在的索引上擴(kuò)展成組合索引,或者在已經(jīng)存在的組合索引上繼續(xù)添加字段。因?yàn)椋饕蕉?,維護(hù)成本就越高,還會(huì)導(dǎo)致插入速度變慢等負(fù)面效應(yīng)。
2、索引創(chuàng)建的條件
哪些情況需要?jiǎng)?chuàng)建索引:
- 頻繁作為查詢條件的字段一般都應(yīng)該創(chuàng)建索引;
- 查詢有多個(gè)條件時(shí),組合索引比單字段索引的性價(jià)比更高;
- 查詢中排序的字段,排序字段若通過索引去訪問將大大提高排序速度,注意單字段索引和組合索引的排序規(guī)則
- 查詢中統(tǒng)計(jì)或分組字段也應(yīng)該建立索引
哪些情況不需要?jiǎng)?chuàng)建索引:
- 集中中的記錄太少或記錄內(nèi)的字段太少;
- 經(jīng)常增刪改的集合或字段;索引提高了查詢速度,同時(shí)也就會(huì)降低更新表的速度,因?yàn)楦卤頃r(shí),不僅要保存數(shù)據(jù),還要保存一下索引文件;因?yàn)槿绻摷蠈懚嘧x少 ,添加索引會(huì)影響寫入性能
- where條件里用不到的字段就不要?jiǎng)?chuàng)建索引
- 數(shù)據(jù)重復(fù)且發(fā)布比較均勻的的字段不適合建索引(唯一性太差的字段不適合建立索引),例如性別,真假值
- 參與列計(jì)算的列不適合建索引
3、索引的空間與命中
在云開發(fā)控制臺(tái)每個(gè)集合都有相應(yīng)的索引管理,在這里除了可以創(chuàng)建索引外,還可以了解每個(gè)索引占據(jù)的空間以及判斷查詢時(shí)索引是否命中的命中數(shù)。每個(gè)索引建議創(chuàng)建的索引數(shù)不要超過5個(gè),索引占據(jù)的空間
三、 索引的原則與注意事項(xiàng)
1、最好是使用唯一索引
當(dāng)唯一性是某種數(shù)據(jù)本身的特征時(shí),指定唯一索引。使用唯一索引需能確保定義的列的數(shù)據(jù)完整性,以提高查詢速度
2、和簡(jiǎn)單的字段為索引
Innodb 表的普通索引都會(huì)保存主鍵的鍵值,所以主鍵要盡可能選擇較短的數(shù)據(jù)類型,可以有效的減少索引的磁盤占用,提高索引的緩存效果。索引的太長首先會(huì)占用大量的磁盤空間,其次索引太長會(huì)使索引變得臃腫,導(dǎo)致索引查詢變慢。通過目錄查詢書籍指定的章節(jié)之所以快,就是因?yàn)樗饕銐蜉p量,如果索引太長那么這個(gè)優(yōu)勢(shì)就不明顯了。而且索引里的數(shù)據(jù)和表里的數(shù)據(jù)本身就是冗余的,如果索引太長,那么磁盤空間浪費(fèi)的就越多。
3、用區(qū)分度比較高的列建索引
具有多個(gè)重復(fù)值的字段,其索引效果最差。比如存放身份證的字段因?yàn)橹刀疾煌?,很容易區(qū)分,索引效果比較好,而用來記錄性別的字段,因?yàn)橹缓小澳小?,“女”,不管搜索哪個(gè)值,都會(huì)得出大約一半的值,這樣的索引對(duì)性能的提升不高。如果有幾個(gè)列都是唯一的,要選擇最常作為訪問條件的列作為索引的主鍵。簡(jiǎn)單枚舉值的列不要建立索引。在條件表達(dá)式中經(jīng)常用到的不同值較多的列上建立索引,在不同值較少的列上不要建立索引,比如性別字段只有男和女,就沒必要建立索引。如果建立索引不但不會(huì)提高查詢效率,反而會(huì)嚴(yán)重降低更新速度。由于我們建立索引并想讓索引能達(dá)到最高性能,這個(gè)時(shí)候我們應(yīng)當(dāng)充分考慮該列是否適合建立索引,可以根據(jù)列的區(qū)分度來判斷,區(qū)分度太低的情況下可以不考慮建立索引,區(qū)分度越高效率越高。
4、索引的字段的值最好不要有空值
索引的字段最好不要有空值,有空值的字段建立索引時(shí)要選擇非唯一性。唯一性的索引是不允許有空值的。
5、索引的字段最好不要參與計(jì)算
索引列不能參與計(jì)算,保持列“干凈”;索引列參與計(jì)算;應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行表達(dá)式操作
6、查詢盡量都走在索引上
保證索引包含的字段獨(dú)立在查詢語句中,不能是在表達(dá)式中,當(dāng)查詢的列都在索引的字段中時(shí),查詢的效率更高,所以應(yīng)該盡量避免使用 select *,需要哪些字段,就只查哪些字段。在索引基數(shù)高的地方建立索引(比如郵箱,用戶名,而不是性別)
7、避免重復(fù)索引和冗余索引
重復(fù)索引:在同一列或者相同順序的幾個(gè)列建立了多個(gè)索引,成為重復(fù)索引,沒有任何意義,刪掉 冗余索引:兩個(gè)或多個(gè)索引所覆蓋的列有重疊,比如對(duì)于列m,n ,加索引index m(m),indexmn(m,n),稱為冗余索引。
8、使用索引獲取有序數(shù)據(jù)
索引本身是有序的,利用有序索引獲取有序數(shù)據(jù)(Using Index)。使用索引來優(yōu)化或者避免排序排序的字段上加入索引,可以提高速度。在頻繁排序或分組(即group by或order by操作)的列上建立索引,如果待排序的列有多個(gè),可以在這些列上建立組合索引
9、組合索引遵循最左前綴原則
建立組合索引,要同時(shí)考慮列查詢的頻率和列的區(qū)分度,區(qū)分度大的優(yōu)先放在前面。比如一張全球人口的用戶表,該表有性別,國籍,年齡等字段。那么一般情況下國籍的區(qū)分度就要比性別的區(qū)分度更高,比如滿足中國人這個(gè)條件的要比滿足男人這個(gè)條件的人要更少。因此建組合索引時(shí)國籍優(yōu)先考慮放在性別的前面。
10、索引碎片與維護(hù)
在數(shù)據(jù)表長期的更改過程中,索引文件和數(shù)據(jù)文件都會(huì)產(chǎn)生空洞,形成碎片。修復(fù)表的過程十分耗費(fèi)資源,可以用比較長的周期修復(fù)表。
11、注意索引的唯一性和非唯一性
唯一索引一定要小心使用,它帶有唯一約束,由于前期需求不明等情況下,可能造成我們對(duì)于唯一列的誤判。
12、建議最好不要用隨機(jī)生成的_id做主鍵
最好是使用自增ID字段做索引的主鍵,而不要使用隨機(jī)的_id做主鍵,因?yàn)榉沁f增的主鍵會(huì)導(dǎo)致頻繁的頁分裂,從而降低了插入的效率。所以一般情況下,我們會(huì)在表中使用一個(gè)自增ID字段來代替_id(使用原子更新指令inc來做自增),用該字段來作表的主鍵。如果需要按照_id查詢時(shí),查找就需要回表,查找的效率會(huì)低一點(diǎn)。如果表中只需要一個(gè)_id的唯一索引,那么就可以使用_id來做主鍵;如果不滿足這個(gè)條件就用自增ID做索引;
當(dāng)前題目:創(chuàng)新互聯(lián)小程序云教程:云開發(fā)索引
轉(zhuǎn)載來于:http://www.5511xx.com/article/cooodoe.html


咨詢
建站咨詢
