Index 能夠提高查詢的性能,如果沒(méi)有Index,MongoDB必須掃描整個(gè)collection,從collection的第一個(gè)doc開(kāi)始,直到最后一個(gè)doc,即使第一個(gè)doc之后的所有doc都不滿足查詢條件。如果在Collection上有合適的Index,例如,unique index,那么MongoDB在按照index key查找到一個(gè)doc之后,就不會(huì)繼續(xù)對(duì)其他doc查詢,極大地提高查詢性能。
MongoDB的 Index 結(jié)構(gòu)跟關(guān)系型DB的NonClustered Index相似,都是BTree結(jié)構(gòu),在每個(gè)leaf node中,除了index key之外,還存儲(chǔ)相應(yīng)doc在disk上的地址。在MongoDB中,沒(méi)有clustered index,因此,Collection初始的物理存儲(chǔ)跟doc插入的順序有關(guān),MongoDB按照doc插入的順序,依次將doc存儲(chǔ)在disk上,插入順序上相鄰的doc在disk的物理位置上也是相鄰的;對(duì)doc的修改可能對(duì) collection 的物理存儲(chǔ)發(fā)生變化,如果doc的修改不會(huì)導(dǎo)致doc的size增加,那么doc會(huì)繼續(xù)存儲(chǔ)在原來(lái)的存儲(chǔ)空間中,而不會(huì)對(duì)collection的物理存儲(chǔ)有影響,一旦修改操作導(dǎo)致doc的size增加,導(dǎo)致doc發(fā)生移動(dòng),那么collection的物理存儲(chǔ)就會(huì)發(fā)生變化。
一,doc的移動(dòng)影響collection的物理存儲(chǔ)
如果數(shù)據(jù)修改增加了doc的size,使其不能繼續(xù)存放在原來(lái)的存儲(chǔ)空間中,那么MongoDB必須將其移動(dòng)到collection的末尾,原先的存儲(chǔ)空間被閑置,導(dǎo)致doc的存儲(chǔ)密度下降,會(huì)嚴(yán)重影響查詢性能。doc的移動(dòng)過(guò)程是非常慢的,相當(dāng)于在一個(gè)原子操作中,先做doc的 delete 操作,后做doc的 insert 操作。
doc移動(dòng)的過(guò)程如下圖所示:
對(duì)doc B進(jìn)行修改,使其Size增大,原先的位置不能容納B,MongoDB將B移動(dòng)在Collection的末尾。原來(lái)的存儲(chǔ)空間被閑置。