1. 程式人生 > >MongoDB3.2---Profiling慢查詢詳解

MongoDB3.2---Profiling慢查詢詳解

 

https://blog.csdn.net/jianlong727/article/details/56676985

 

官方查詢地址:https://docs.mongodb.com/v3.2/tutorial/manage-the-database-profiler/
在很多情況下,DBA都要對資料庫的效能進行分析處理,找出降低效能的根源
而Mongo就有一種分析工具來檢測並追蹤影響效能的慢查詢---Profile
有兩種方式可以控制Profiling的開關和級別,
第一種是直接在啟動引數中進行設定,如下:
如果想要全域性開啟Profiling,則可以在mongod啟動時加上引數
mongod --profile 1 --slowms100         # 1表示追蹤級別,100表示慢查詢判定時間(ms)
如果是配置檔案中開啟的話,配置如下:
operationProfiling:
     slowOpThresholdMs: 100
     mode: slowOp

第二種是在mongo shell進行實時配置,命令如下:
> db.setProfilingLevel(1,200)          ---1表示level,200表示慢查詢時間(ms),也可以省略時間設定
{ "was" : 1, "slowms" : 100, "ok" : 1 }     ---100表示之前的慢查詢時間設定值
> db.getProfilingStatus()               ---查詢當前慢查詢的狀態資訊
{ "was" : 1, "slowms" : 200 }          ---was後的值表示級別
> db.getProfilingLevel()               ---只查詢Profiling級別可用此命令
1

級別可以取0,1,2 三個值,他們表示的意義如下: 
  0 – 不開啟
  1 – 記錄慢命令 (預設為>100ms)
  2 – 記錄所有命令

Mongo Profile慢查詢記錄直接記錄在db中,記錄位置是當前開啟Profile功能的庫下的system.profile集合中,所以只需要直接查詢這個集合就行
例:
     查詢執行時間大於200ms的Profile記錄:
> db.system.profile.find( { millis : { $gt : 5 } } )

檢視最近的10條記錄
>db.system.profile.find().limit(10).sort( { ts : -1 } ).pretty()

     檢視關於某個collection的相關慢查詢操作:
>db.system.profile.find({ns:'mydb.table1'}).pretty()

show profile命令
此命令查詢執行時間超過1ms的最近5條記錄

對於Profile的相關資訊解釋:
op:操作的型別,比如:insert,query,command,remove...
ns:被查詢目標的名稱空間,一般是資料庫名和collection名的組合
query:查詢的具體語句,如果是insert操作,則會是insert的語句
command:如果操作是一個command,則command語句記錄在此
keysExamined:以前是nscanned,3.2版本之後改為keysExamined,表示執行此次操作所掃描的索引鍵記錄數
updateobj:如果操作是一個update,則update語句記錄在此
ndeleted:此次操作刪除的文件數
ninserted: 此次操作插入的文件數
nModified:此次操作的update的文件數
writeConflicts:如果一個update語句正在操作一個文件,而另一個update同時進行操作此文件,從而造成的衝突數量
locks:此次操作產生鎖的相關資訊
nreturned:此次操作返回的文件數
responseLength:操作結果集的大小,
moved:表明本次update是否移動了硬碟上的資料,如果新記錄比原記錄短,通常不會移動當前記錄,如果新記錄比原記錄長,那麼可能會移動記錄到其它位置,這時候會導致相關索引的更新.磁碟操作更多,加上索引更新,會使得這樣的操作比較慢.(不過這個選在僅針對引擎是MMAPv1)

MongoDB 查詢優化
     如果keysExamined (掃描索引建的記錄數)遠大於nreturned(返回結果的記錄數)的話,那麼我們就要考慮通過加索引來優化記錄定位了。
     responseLength 如果過大,那麼說明我們返回的結果集太大了,可能會影響效能,這時請檢視find函式的第二個引數是否只寫上了你需要的屬性名(限制於僅需要查詢的欄位)。(類似 於MySQL中不要總是select *)
     對於建立索引的建議是:如果很少讀,那麼儘量不要新增索引,因為索引越多,寫操作會越慢。如果讀量很大,那麼建立索引還是比較划算的。

Profiler 的效率
  Profiling 功能肯定是會影響效率的,但是不太嚴重,原因是他使用的是system.profile 來記錄,而system.profile 是一個capped collection 這種collection 在操作上有一些限制和特點,但是效率更高
也可以對system.profile的size進行設定,具體設定如下:
db.setProfilingLevel(0)
 
db.system.profile.drop()
 
db.createCollection( "system.profile", { capped: true, size:4000000 } )
 
db.setProfilingLevel(1)