MongoDB性能篇之創(chuàng)建索引,組合索引,唯一索引,刪除索引和explain執(zhí)行計(jì)劃
一、索引
MongoDB 提供了多樣性的索引支持,索引信息被保存在system.indexes 中,且默認(rèn)總是為_(kāi)id創(chuàng)建索引,它的索引使用基本和MySQL 等關(guān)系型數(shù)據(jù)庫(kù)一樣。其實(shí)可以這樣說(shuō)說(shuō),索引是凌駕于數(shù)據(jù)存儲(chǔ)系統(tǒng)之上的另一層系統(tǒng),所以各種結(jié)構(gòu)迥異的存儲(chǔ)都有相同或相似的索引實(shí)現(xiàn)及使用接口并不足為 奇。
1.基礎(chǔ)索引
在字段age 上創(chuàng)建索引,1(升序);-1(降序):
db.users.ensureIndex({age:1})
_id 是創(chuàng)建表的時(shí)候自動(dòng)創(chuàng)建的索引,此索引是不能夠刪除的。當(dāng)系統(tǒng)已有大量數(shù)據(jù)時(shí),創(chuàng)建索引就是個(gè)非常耗時(shí)的活,我們可以在后臺(tái)執(zhí)行,只需指定“backgroud:true”即可。
db.t3.ensureIndex({age:1} , {backgroud:true})
2.文檔索引
索引可以任何類型的字段,甚至文檔:
db.factories.insert( { name: "wwl", addr: { city: "Beijing", state: "BJ" } } ); //在addr 列上創(chuàng)建索引 db.factories.ensureIndex( { addr : 1 } ); //下面這個(gè)查詢將會(huì)用到我們剛剛建立的索引 db.factories.find( { addr: { city: "Beijing", state: "BJ" } } ); //但是下面這個(gè)查詢將不會(huì)用到索引,因?yàn)椴樵兊捻樞蚋饕⒌捻樞虿灰粯? db.factories.find( { addr: { state: "BJ" , city: "Beijing"} } );
3. 組合索引
跟其它數(shù)據(jù)庫(kù)產(chǎn)品一樣,MongoDB 也是有組合索引的,下面我們將在addr.city 和addr.state上建立組合索引。當(dāng)創(chuàng)建組合索引時(shí),字段后面的1 表示升序,-1 表示降序,是用1 還是用-1 主要是跟排序的時(shí)候或指定范圍內(nèi)查詢 的時(shí)候有關(guān)的。
db.factories.ensureIndex( { "addr.city" : 1, "addr.state" : 1 } ); // 下面的查詢都用到了這個(gè)索引 db.factories.find( { "addr.city" : "Beijing", "addr.state" : "BJ" } ); db.factories.find( { "addr.city" : "Beijing" } ); db.factories.find().sort( { "addr.city" : 1, "addr.state" : 1 } ); db.factories.find().sort( { "addr.city" : 1 } )
4. 唯一索引
只需在ensureIndex 命令中指定”unique:true”即可創(chuàng)建唯一索引。例如,往表t4 中插入2 條記錄:
db.t4.ensureIndex({firstname: 1, lastname: 1}, {unique: true});
5.強(qiáng)制使用索引
hint 命令可以強(qiáng)制使用某個(gè)索引。
db.t5.find({age:{$lt:30}}).hint({name:1, age:1}).explain()
6.刪除索引
//刪除t3 表中的所有索引 db.t3.dropIndexes() //刪除t4 表中的firstname 索引 db.t4.dropIndex({firstname: 1})
二、explain執(zhí)行計(jì)劃
MongoDB 提供了一個(gè) explain 命令讓我們獲知系統(tǒng)如何處理查詢請(qǐng)求。利用 explain 命令,我們可以很好地觀察系統(tǒng)如何使用索引來(lái)加快檢索,同時(shí)可以針對(duì)性優(yōu)化索引。
db.t5.ensureIndex({name:1}) db.t5.ensureIndex({age:1}) db.t5.find({age:{$gt:45}}, {name:1}).explain() { "cursor" : "BtreeCursor age_1", "nscanned" : 0, "nscannedObjects" : 0, "n" : 0, "millis" : 0, "nYields" : 0, "nChunkSkips" : 0, "isMultiKey" : false, "indexOnly" : false, "indexBounds" : { "age" : [ [45,1.7976931348623157e+308] ] } }
字段說(shuō)明:
cursor: 返回游標(biāo)類型(BasicCursor 或 BtreeCursor)
nscanned: 被掃描的文檔數(shù)量
n: 返回的文檔數(shù)量
millis: 耗時(shí)(毫秒)
indexBounds: 所使用的索引
三、優(yōu)化器profile
在MySQL 中,慢查詢?nèi)罩臼墙?jīng)常作為我們優(yōu)化數(shù)據(jù)庫(kù)的依據(jù),那在MongoDB 中是否有類似的功能呢?答案是肯定的,那就是MongoDB Database Profiler。
1.開(kāi)啟profiling功能
有兩種方式可以控制 Profiling 的開(kāi)關(guān)和級(jí)別,第一種是直接在啟動(dòng)參數(shù)里直接進(jìn)行設(shè)置。啟動(dòng)MongoDB 時(shí)加上–profile=級(jí)別 即可。也可以在客戶端調(diào)用db.setProfilingLevel(級(jí)別) 命令來(lái)實(shí)時(shí)配置,Profiler 信息保存在system.profile 中。我們可以通過(guò)db.getProfilingLevel()命令來(lái)獲取當(dāng)前的Profile 級(jí)別,類似如下操作:
db.setProfilingLevel(2);
上面profile 的級(jí)別可以取0,1,2 三個(gè)值,他們表示的意義如下:
0 – 不開(kāi)啟
1 – 記錄慢命令 (默認(rèn)為>100ms)
2 – 記錄所有命令
Profile 記錄在級(jí)別1 時(shí)會(huì)記錄慢命令,那么這個(gè)慢的定義是什么?上面我們說(shuō)到其默認(rèn)為100ms,當(dāng)然有默認(rèn)就有設(shè)置,其設(shè)置方法和級(jí)別一樣有兩種,一種是通過(guò)添加 –slowms 啟動(dòng)參數(shù)配置。第二種是調(diào)用db.setProfilingLevel 時(shí)加上第二個(gè)參數(shù):
db.setProfilingLevel( level , slowms ) db.setProfilingLevel( 1 , 10 );
2.查詢 Profiling 記錄
與MySQL 的慢查詢?nèi)罩静煌?,MongoDB Profile 記錄是直接存在系統(tǒng)db 里的,記錄位置system.profile ,所以,我們只要查詢這個(gè)Collection 的記錄就可以獲取到我們的 Profile 記錄了。列出執(zhí)行時(shí)間長(zhǎng)于某一限度(5ms)的 Profile 記錄:
db.system.profile.find( { millis : { $gt : 5 } } )
MongoDB Shell 還提供了一個(gè)比較簡(jiǎn)潔的命令show profile,可列出最近5 條執(zhí)行時(shí)間超過(guò)1ms 的 Profile 記錄。
四、常用性能優(yōu)化方案
創(chuàng)建索引
限定返回結(jié)果數(shù)
只查詢使用到的字段
采用capped collection
采用Server Side Code Execution
使用Hint,強(qiáng)制使用索引
采用Profiling
五、性能監(jiān)控工具
1. mongosniff
此工具可以從底層監(jiān)控到底有哪些命令發(fā)送給了MongoDB 去執(zhí)行,從中就可以進(jìn)行分析:以root 身份執(zhí)行:
$./mongosniff --source NET lo
然后其會(huì)監(jiān)控位到本地以localhost 監(jiān)聽(tīng)默認(rèn)27017 端口的MongoDB 的所有包請(qǐng)求。
2.Mongostat
此工具可以快速的查看某組運(yùn)行中的MongoDB 實(shí)例的統(tǒng)計(jì)信息 字段說(shuō)明:
insert: 每秒插入量
query: 每秒查詢量
update: 每秒更新量
delete: 每秒刪除量
locked: 鎖定量
qr | qw: 客戶端查詢排隊(duì)長(zhǎng)度(讀|寫)
ar | aw: 活躍客戶端量(讀|寫)
conn: 連接數(shù)
time: 當(dāng)前時(shí)間
它每秒鐘刷新一次狀態(tài)值,提供良好的可讀性,通過(guò)這些參數(shù)可以觀察到一個(gè)整體的性能情況。
3. db.serverStatus
這個(gè)命令是最常用也是最基礎(chǔ)的查看實(shí)例運(yùn)行狀態(tài)的命令之一。
4.db.stats
db.stats 查看數(shù)據(jù)庫(kù)狀態(tài)信息。
以上所述是小編給大家介紹的MongoDB性能篇之創(chuàng)建索引,組合索引,唯一索引,刪除索引和explain執(zhí)行計(jì)劃的相關(guān)知識(shí),希望對(duì)大家有所幫助!
- MongoDB索引使用詳解
- MongoDB中唯一索引(Unique)的那些事
- MongoDB的基礎(chǔ)查詢和索引操作方法總結(jié)
- MongoDB中創(chuàng)建索引需要注意的事項(xiàng)
- 深入理解MongoDB的復(fù)合索引
- mongodb處理中文索引與查找字符串詳解
- MongoDB查詢字段沒(méi)有創(chuàng)建索引導(dǎo)致的連接超時(shí)異常解案例分享
- 關(guān)于MongoDB索引管理-索引的創(chuàng)建、查看、刪除操作詳解
- MongoDB自動(dòng)刪除過(guò)期數(shù)據(jù)的方法(TTL索引)
- 關(guān)于對(duì)MongoDB索引的一些簡(jiǎn)單理解
相關(guān)文章
mongodb字段值自增長(zhǎng)實(shí)現(xiàn)代碼
這篇文章主要介紹了mongodb字段值自增長(zhǎng)實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01ubuntu安裝mongodb創(chuàng)建賬號(hào)和庫(kù)及添加坐標(biāo)索引的流程分析
這篇文章主要介紹了ubuntu安裝mongodb創(chuàng)建賬號(hào)和庫(kù)及添加坐標(biāo)索引的流程分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10MongoDB快速入門筆記(六)之MongoDB的文檔修改操作
這篇文章主要介紹了MongoDB快速入門筆記(六)之MongoDB的文檔修改操作的相關(guān)資料,需要的朋友可以參考下2016-06-06mongodb出現(xiàn)id重復(fù)問(wèn)題的簡(jiǎn)單解決辦法
近期在使用mongodb的過(guò)程中遇到一次表中有_id字段重復(fù)的記錄(相同_id的有兩條),著實(shí)嚇了一大跳,這篇文章主要給大家介紹了關(guān)于mongodb出現(xiàn)id重復(fù)問(wèn)題的簡(jiǎn)單解決辦法,需要的朋友可以參考下2021-12-12MongoDB副本集丟失數(shù)據(jù)的測(cè)試實(shí)例教程
這篇文章主要給大家介紹了關(guān)于MongoDB副本集丟失數(shù)據(jù)的測(cè)試的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用MongoDB具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05MongoDB基礎(chǔ)入門之創(chuàng)建、刪除集合操作
這篇文章主要給大家介紹了關(guān)于MongoDB基礎(chǔ)入門之集合操作的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03