- 論壇徽章:
- 0
|
Mongo Database Profiler
在MySQL中,慢查詢?nèi)罩臼墙?jīng)常作為我們優(yōu)化數(shù)據(jù)庫的依據(jù),那在MongoDB中是否有類似的功能呢?答案是肯定的,那就是Mongo Database Profiler.不僅有,而且還有一些比MySQL的Slow Query Log更詳細(xì)的信息。它就是我們這篇文章的主題。
開啟 Profiling 功能
有兩種方式可以控制 Profiling 的開關(guān)和級(jí)別,第一種是直接在啟動(dòng)參數(shù)里直接進(jìn)行設(shè)置。
啟動(dòng)MongoDB時(shí)加上–profile=級(jí)別 即可。
也可以在客戶端調(diào)用db.setProfilingLevel(級(jí)別) 命令來實(shí)時(shí)配置。可以通過db.getProfilingLevel()命令來獲取當(dāng)前的Profile級(jí)別。
> db.setProfilingLevel(2);
{"was" : 0 , "ok" : 1}
> db.getProfilingLevel()上面斜體的級(jí)別可以取0,1,2 三個(gè)值,他們表示的意義如下:
0 – 不開啟
1 – 記錄慢命令 (默認(rèn)為>100ms)
2 – 記錄所有命令
Profile 記錄在級(jí)別1時(shí)會(huì)記錄慢命令,那么這個(gè)慢的定義是什么?上面我們說到其默認(rèn)為100ms,當(dāng)然有默認(rèn)就有設(shè)置,其設(shè)置方法和級(jí)別一樣有兩種,一種是通過添加–slowms啟動(dòng)參數(shù)配置。第二種是調(diào)用db.setProfilingLevel時(shí)加上第二個(gè)參數(shù):
db.setProfilingLevel( level , slowms )
db.setProfilingLevel( 1 , 10 );查詢 Profiling 記錄
與MySQL的慢查詢?nèi)罩静煌,Mongo Profile 記錄是直接存在系統(tǒng)db里的,記錄位置 system.profile ,所以,我們只要查詢這個(gè)Collection的記錄就可以獲取到我們的 Profile 記錄了。
> db.system.profile.find()
{"ts" : "Thu Jan 29 2009 15:19:32 GMT-0500 (EST)" , "info" : "query test.$cmd ntoreturn:1 reslen:66 nscanned:0
query: { profile: 2 } nreturned:1 bytes:50" , "millis" : 0}
db.system.profile.find( { info: /test.foo/ } )
{"ts" : "Thu Jan 29 2009 15:19:40 GMT-0500 (EST)" , "info" : "insert test.foo" , "millis" : 0}
{"ts" : "Thu Jan 29 2009 15:19:42 GMT-0500 (EST)" , "info" : "insert test.foo" , "millis" : 0}
{"ts" : "Thu Jan 29 2009 15:19:45 GMT-0500 (EST)" , "info" : "query test.foo ntoreturn:0 reslen:102 nscanned:2
query: {} nreturned:2 bytes:86" , "millis" : 0}
{"ts" : "Thu Jan 29 2009 15:21:17 GMT-0500 (EST)" , "info" : "query test.foo ntoreturn:0 reslen:36 nscanned:2
query: { $not: { x: 2 } } nreturned:0 bytes:20" , "millis" : 0}
{"ts" : "Thu Jan 29 2009 15:21:27 GMT-0500 (EST)" , "info" : "query test.foo ntoreturn:0 exception bytes:53" , "millis" : 88}列出執(zhí)行時(shí)間長(zhǎng)于某一限度(5ms)的 Profile 記錄:
> db.system.profile.find( { millis : { $gt : 5 } } )
{"ts" : "Thu Jan 29 2009 15:21:27 GMT-0500 (EST)" , "info" : "query test.foo ntoreturn:0 exception bytes:53" , "millis" : 88}查看最新的 Profile 記錄:
db.system.profile.find().sort({$natural:-1})Mongo Shell 還提供了一個(gè)比較簡(jiǎn)潔的命令show profile,可列出最近5條執(zhí)行時(shí)間超過1ms的 Profile 記錄。
Profile 信息內(nèi)容詳解:
ts-該命令在何時(shí)執(zhí)行.
millis Time-該命令執(zhí)行耗時(shí),以毫秒記.
info-本命令的詳細(xì)信息.
query-表明這是一個(gè)query查詢操作.
ntoreturn-本次查詢客戶端要求返回的記錄數(shù).比如, findOne()命令執(zhí)行時(shí) ntoreturn 為 1.有l(wèi)imit(n) 條件時(shí)ntoreturn為n.
query-具體的查詢條件(如x>3).
nscanned-本次查詢掃描的記錄數(shù).
reslen-返回結(jié)果集的大小.
nreturned-本次查詢實(shí)際返回的結(jié)果集.
update-表明這是一個(gè)update更新操作.
fastmod-Indicates a fast modify operation. See Updates. These operations are normally quite fast.
fastmodinsert – indicates a fast modify operation that performed an upsert.
upsert-表明update的upsert參數(shù)為true.此參數(shù)的功能是如果update的記錄不存在,則用update的條件insert一條記錄.
moved-表明本次update是否移動(dòng)了硬盤上的數(shù)據(jù),如果新記錄比原記錄短,通常不會(huì)移動(dòng)當(dāng)前記錄,如果新記錄比原記錄長(zhǎng),那么可能會(huì)移動(dòng)記錄到其它位置,這時(shí)候會(huì)導(dǎo)致相關(guān)索引的更新.磁盤操作更多,加上索引更新,會(huì)使得這樣的操作比較慢.
insert-這是一個(gè)insert插入操作.
getmore-這是一個(gè)getmore 操作,getmore通常發(fā)生在結(jié)果集比較大的查詢時(shí),第一個(gè)query返回了部分結(jié)果,后續(xù)的結(jié)果是通過getmore來獲取的。
MongoDB 查詢優(yōu)化
如果nscanned(掃描的記錄數(shù))遠(yuǎn)大于nreturned(返回結(jié)果的記錄數(shù))的話,那么我們就要考慮通過加索引來優(yōu)化記錄定位了。
reslen 如果過大,那么說明我們返回的結(jié)果集太大了,這時(shí)請(qǐng)查看find函數(shù)的第二個(gè)參數(shù)是否只寫上了你需要的屬性名。(類似 于MySQL中不要總是select *)
對(duì)于創(chuàng)建索引的建議是:如果很少讀,那么盡量不要添加索引,因?yàn)樗饕蕉,寫操作?huì)越慢。如果讀量很大,那么創(chuàng)建索引還是比較劃算的。(和RDBMS一樣,貌似是廢話 -_-!!)
MongoDB 更新優(yōu)化
如果寫查詢量或者update量過大的話,多加索引是會(huì)有好處的。以及~~~~(省略N字,和RDBMS差不多的道理)
Use fast modify operations when possible (and usually with these, an index). See Updates.
Profiler 的效率
Profiling 功能肯定是會(huì)影響效率的,但是不太嚴(yán)重,原因是他使用的是system.profile 來記錄,而system.profile 是一個(gè)capped collection 這種collection 在操作上有一些限制和特點(diǎn),但是效率更高。
本文轉(zhuǎn)載自:http://lgone.com/html/y2010/774.html
|
|