密集索引
mongodb索引默認(rèn)是密集型的疲眷。在一個(gè)有索引的集合里禾蚕,每個(gè)文檔都會(huì)有對(duì)應(yīng)的索引項(xiàng),哪怕文檔中沒有被索引鍵也是如此狂丝。例如换淆,給文檔的name字段建索引,而有的文檔并沒有name字段几颜,那么name字段索引里會(huì)有null值倍试,可以這樣查詢name為null值的文檔:db.products.find({name: null})。
稀疏索引
在稀疏索引里蛋哭,只會(huì)出現(xiàn)被索引鍵有值的文檔县习。如果想創(chuàng)建稀疏索引,指定{sparse: true}就可以了具壮。例如准颓,可以像下面這樣在name上創(chuàng)建一個(gè)唯一性稀疏索引:
db.products.ensureIndex({name: 1}, {unique: true, sparse: true})
比較
兩種情況下不太適合使用默認(rèn)的密集型索引:
一種是希望在并非出現(xiàn)在集合所有文檔內(nèi)的字段上增加唯一性索引時(shí)。舉例來說棺妓,你明確希望在每個(gè)產(chǎn)品的sku字段上增加唯一性索引攘已。但是出于某些原因,假設(shè)產(chǎn)品在還未分配sku時(shí)就加入系統(tǒng)了怜跑。如果sku字段上有唯一性索引样勃,而你希望插入多個(gè)沒有sku的產(chǎn)品,那么第一次插入會(huì)成功性芬,但后續(xù)插入都會(huì)失敗峡眶,因?yàn)樗饕镆呀?jīng)存在一個(gè)sku為null的項(xiàng)了。這種情況下密集型索引并不適合植锉,你所需要的是稀疏索引(sparse index)辫樱。
另一種適用稀疏索引的情況:集合中大量文檔都不包含被索引鍵。例如俊庇,假設(shè)允許對(duì)電子商務(wù)網(wǎng)站進(jìn)行匿名評(píng)論狮暑。這種情況下鸡挠,半數(shù)評(píng)論都可能缺少user_id字段,如果那個(gè)字段上有索引搬男,那么該索引中一半的項(xiàng)都會(huì)是null拣展。出于兩個(gè)原因,這種情況的效率會(huì)很差缔逛。第一备埃,這會(huì)增加索引的大小。第二褐奴,在添加和刪除帶null值user_id字段的文檔時(shí)也要求更新索引按脚。
如果很少(或不會(huì))對(duì)匿名評(píng)論進(jìn)行查詢,那么可以選擇在user_id上構(gòu)建一個(gè)稀疏索引歉糜。