MongoDB 是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫(kù)。由 C++ 語(yǔ)言編寫。旨在為 WEB 應(yīng)用提供可擴(kuò)展的高性能數(shù)據(jù)存儲(chǔ)解決方案。MongoDB索引幾乎和關(guān)系型數(shù)據(jù)庫(kù)的索引一樣.MongoDB的查詢優(yōu)化器能夠使用這種數(shù)據(jù)結(jié)構(gòu)來(lái)快速的對(duì)集合(collection)中的文檔(collection)進(jìn)行尋找和排序.準(zhǔn)確來(lái)說(shuō),這些索引是通過(guò)B-Tree索引來(lái)實(shí)現(xiàn)的。在命令行中,可以通過(guò)調(diào)用ensureIndex()函數(shù)來(lái)建立索引,該函數(shù)指定一個(gè)到多個(gè)需要索引的字段,下面介紹mongodb索引如何優(yōu)化
一、索引簡(jiǎn)介
例如如下數(shù)據(jù)
db.refactor.insert({"username":"refactor","age":24,"isactive":true}) db.refactor.insert({"username":"refactor","age":30,"isactive":false}) db.refactor.insert({"username":"aaaaa","age":24,"isactive":false}) db.refactor.insert({"username":"aaaaa","age":34,"isactive":true}) db.refactor.insert({"username":"sssssss","age":24,"isactive":true}) db.refactor.insert({"username":"tttttt","age":24,"isactive":true}) db.refactor.insert({"username":"tttttt","age":54,"isactive":true}) db.refactor.insert({"username":"bbbbb","age":24,"isactive":false}) db.refactor.insert({"username":"rrrrr","age":24,"isactive":true}) db.refactor.insert({"username":"rrrrr","age":54,"isactive":false})
要按照username鍵進(jìn)行查找,就可以在此鍵上建立索引,來(lái)提高查詢速度.
db.refactor.ensureIndex({"username":1})
要按照username,age鍵進(jìn)行查找,就可以在此鍵上建立索引,來(lái)提高查詢速度.
db.refactor.ensureIndex({"age":1,"username":1})
傳遞給ensureIndex的文檔是一組值為1或-1的鍵,1為升序,-1為降序,表示索引的創(chuàng)建方向.若索引只有一個(gè)鍵,則方向無(wú)關(guān)緊要.
若是有多個(gè)鍵,就得考慮索引的方向問(wèn)題了.
二、mongodb自帶的就有監(jiān)控,根據(jù)這些監(jiān)控信息,可以做為優(yōu)化的依據(jù)
1、explain執(zhí)行計(jì)劃
MongoDB提供了一個(gè)explain命令讓我們獲知系統(tǒng)如何處理查詢請(qǐng)求。利用explain命令,我們可以很好地觀察系統(tǒng)如何使用索引來(lái)加快檢索同時(shí)可以針對(duì)性優(yōu)化索引。
幾個(gè)關(guān)鍵的字段說(shuō)明
cursor:返回游標(biāo)類型(BasicCursor或BtreeCursor)
nscanned:被掃描的文檔數(shù)量
n:返回的文檔數(shù)量
millis:耗時(shí)(毫秒)
indexBounds:所使用的索引
例如
SQL 代碼
>db.order.ensureIndex({"user.uid":1}) >db.order.find({ "status": 1.0, "user.uid": { $gt: 2663199.0 } }).explain() { "cursor" : "BtreeCursor user.uid_1", "nscanned" : 337800, "nscannedObjects" : 337800, "n" : 337800, "millis" : 1371, "nYields" : 0, "nChunkSkips" : 0, "isMultiKey" : false, "indexOnly" : false, "indexBounds" : { "user.uid" : [ [ 2663199, 1.7976931348623157e+308 ] ] } }
2、優(yōu)化器profile
在MySQL中慢查詢?nèi)罩臼墙?jīng)常作為我們優(yōu)化數(shù)據(jù)庫(kù)的依據(jù)那在MongoDB中是否有類似的功能呢?答案是肯定的那就是MongoDBDatabaseProfiler。所以MongoDB不僅有而且還有一些比MySQL的SlowQueryLog更詳細(xì)的信息。
mongodb把要輸出的慢語(yǔ)句,存在于db.system.profile。與mysql的slowlog配置相似,需要進(jìn)行參數(shù)設(shè)置,mongo才會(huì)輸出慢語(yǔ)句到profile。有兩個(gè)參數(shù)來(lái)控制profile的輸出
db.setProfilingLevel(level,slowms);
默認(rèn)為0 不輸出 1按第二個(gè)參數(shù)時(shí)間閥值(單位為毫秒)輸出 2全部輸出。通常我們?cè)谡{(diào)優(yōu)的時(shí)候都在測(cè)試環(huán)境打開(kāi)參數(shù)。在生產(chǎn)環(huán)境下一般不輸出profile。
比如
> db.system.profile.find({millis:{$gt:1000}})
就可以輸出,查詢時(shí)間大于1秒的慢語(yǔ)句。
profile輸出的各項(xiàng)值的含義是
ts:命令執(zhí)行時(shí)間
info:命令的內(nèi)容
query:代表查詢
order.order: 代表查詢的庫(kù)與集合
reslen:返回的結(jié)果集大小,byte數(shù)
nscanned:掃描記錄數(shù)量
nquery:后面是查詢條件
nreturned:返回記錄數(shù)及用時(shí)
millis:所花時(shí)間
如果發(fā)現(xiàn)時(shí)間比較長(zhǎng),那么就需要作優(yōu)化。
比如
(1)、nscanned數(shù)很大,或者接近記錄總數(shù),那么可能沒(méi)有用到索引查詢。
(2)、reslen很大,有可能返回沒(méi)必要的字段。
(3)、nreturned很大,那么有可能查詢的時(shí)候沒(méi)有加限制。
三、MongoDB的索引選擇機(jī)制
MongoDB的優(yōu)化程序會(huì)在對(duì)比中選擇更優(yōu)秀的索引。
首先,它會(huì)給查詢做一個(gè)初步的“最佳索引”;
其次,假如這個(gè)最佳索引不存在它會(huì)做嘗試來(lái)選出表現(xiàn)最好的索引;
最后,優(yōu)化器還會(huì)記住所有類似查詢的選擇(只到大規(guī)模文件變動(dòng)或者索引上的變動(dòng))。
那么優(yōu)化器是如何定義查詢的“最佳索引”。最佳索引必須包含查詢中所有可以做過(guò)濾及需要排序的字段。此外任何用于范圍掃描的字段以及排序字段都必須排在做等值查詢的字段之后。如果存在不同的最佳索引,那么Mongo將隨機(jī)選擇。
四、MongoDB的索引總結(jié)
1. 等值測(cè)試
索引中加入所有需要做等值測(cè)試的字段,任意順序。
2. 排序字段(多排序字段的升/降序問(wèn)題 )
根據(jù)查詢的順序有序的向索引中添加字段。
3. 范圍過(guò)濾
以字段的基數(shù)(Collection中字段的不同值的數(shù)量)從低到高的向索引中添加范圍過(guò)濾字段。
4、如果索引中的等值或者范圍查詢字段不能過(guò)濾出Collection中90%以上的文檔,那么把它移除索引估計(jì)會(huì)更好一些。
5、索引使得可以通過(guò)關(guān)鍵字段獲取數(shù)據(jù),能夠使得快速查詢和更新數(shù)據(jù)。但是,必須注意的是,索引也會(huì)在插入和刪除的時(shí)候增加一些系統(tǒng)的負(fù)擔(dān)。往集合中插入數(shù)據(jù)的時(shí)候,索引的字段必須加入到B-Tree中去,因此,索引適合建立在讀遠(yuǎn)多于寫的數(shù)據(jù)集上,對(duì)于寫入頻繁的集合,在某些情況下,索引反而有副作用。不過(guò)大多數(shù)集合都是讀頻繁的集合,所以集合在大多數(shù)情況下是有用的。
6、如果數(shù)據(jù)集合比較?。ㄍǔP∮?M),使用sort()而不需要建立索引就能夠返回?cái)?shù)據(jù)。在這種情況下,做好聯(lián)合使用limit()和sort()。
關(guān)于Mongodb索引的優(yōu)化就給大家介紹這么多,希望對(duì)大家有所幫助!
標(biāo)簽:景德鎮(zhèn) 邯鄲 本溪 丹東 昭通 大理 鶴崗 吉安
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Mongodb索引的優(yōu)化》,本文關(guān)鍵詞 Mongodb,索引,的,優(yōu)化,Mongodb,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。