MongoDB的性能优化
? ? ? 說到數據庫方面的優化,我們首先想到的是利用索引技術,mongoDB作為數據庫的一種,利用索引來提高查詢效率同樣適用。下面就我在mongoDB的日常工作中經常使用到的性能優化談談自己的理解。
一:利用explain執行計劃來查看系統執行過程
? ? ?MongoDB本身提供了一個explain()命令來獲取系統執行查詢的處理過程,如下圖:
重要字段說明如下:
* cursor:返回的游標類型,一般分為BasicCursor(系統默認游標)和BtreeCursor(基于樹的游標)。
*nscanned:被掃描的文檔數量。
*n:返回的文檔數量。
*millis:執行查詢所消耗的時間,單位為毫秒。
*indexOnly:是否使用索引。
*indexBound:所使用的索引列表。
下面我們建立索引,來看看explain的執行過程:
????? 上圖中可以看出,建立索引后游標類型變成了基于樹狀的Btree結構游標,搜索速度快,從而大大提高了執行查詢效率。
?????? 索引可以提高查詢性能,但有一點需要注意的是,索引并不是越多越好,如果建立過多,系統性能反而會下降。因為每當你建立一個索引時,系統都會建立一個索引表,用于檢索指定的列,下次當你對已建立的索引列進行插入或者修改時,數據庫都會對原來的索引表進行重新排序,在這過程中會非常消耗性能。
二:優化器Profiler解析
??????? Mongodb本身帶有一種profiler機制,可以方便地記錄所有耗時的操作,以便于調優。
開啟profiler功能有兩種方法:
第一種就是直接在啟動參數里面進行設置,就在啟動mongodb時候添加-profile=“級別“:
mongod --profile=1 --slowms=15
第二種就是在客戶端執行“db.setProfilingLevel(級別,slowms)”命令:
db.setProfilingLevel(0,20)
這里的“級別”分為:0(不開啟),1(記錄慢命令),2(記錄所有命令)。slowms參數代表慢操作記錄的開始時間,默認為100ms。
? ? ? ? 需要注意的是,慢操作記錄的開始時間slowms會應用到整個mongod實例中,當你改變了記錄開始時間,你會改變整個數據庫實例狀態。這一點非常重要,官網中有特別指出:
當你開啟優化器profiler時,系統會自動在數據庫中創建一個system.profile集合,這個集合會默認記錄所有的慢操作日志。
查詢集合結果如下:
>db.system.profile.find() { "ts" : ISODate("2016-06-16T19:45:10.359Z"), "info" : "query test.system.profile reslen:36 nscanned:0 \nquery: {} nreturned:0 bytes:20", "millis" : 0 } { "ts" : ISODate("2016-06-16T19:45:13.562Z"), "info" : "query test.$cmd ntoreturn:1 command: { count: \"system.profile\", query: {}, fields: {} } reslen:64 bytes:48", "millis" : 0 } { "ts" : ISODate("2016-06-16T19:45:13.562Z"), "info" : "query test.system.profile ntoreturn:5 reslen:36 nscanned:2 \nquery: { query: { millis: { $gt: 0.0 } }, orderby: { $natural: -1.0 } } nreturned:0 bytes:20", "millis" : 0 } { "ts" : ISODate("2016-06-16T19:45:17.171Z"), "info" : "query test.emp reslen:261 nscanned:5 \nquery: {} nreturned:5 bytes:245", "millis" : 0 } 主要參數說明如下:
ts:該命令執行的時間。
info:本命令的詳細信息。
reslen:返回結果集的大小。
nscanned:本次查詢掃描的記錄數。
nretured:本次查詢時間返回的結果集。
millis:該命令執行的耗時。單位為毫秒
profile分析數據查詢示例:
如何改變system.profile集合的大小?
例如,你需要創建一個400000bytes的system.profile集合,在mongo腳本執行以下命令:
三:性能優化總結
?方法1:采用Index索引技術。如前面所述,索引并不是越多越好,那什么情況下建立索引最好呢?當你數據庫的總記錄數遠大于你需要返回結果的記錄,并且讀請求較多的時候,創建索引是一個非常好的選擇。
方法2:只查詢你需要的部分字段,不要查詢所有字段。這種方法很好理解。比如說一個銀行的客戶信息存儲非常大,但我們只需要查詢出所有客戶姓名字段即可,這樣比在數據庫調取出客戶所有信息顯然快很多。
方法3:利用優化器Profiler。如前面所述,開啟profile功能會影響系統效率的,但影響效果較小。因為它采用的是system.profile集合來記錄,這個集合是一個Capped Collction,存儲查詢效率高。
方法4:直接使用Capped Collction。這個集合其實是一個具有固定大小,默認基于insert次序排序,并且采用FIFO算法的集合(詳細解釋會在后面文章中指出),讀寫效率比普通的Collection高。
方法5:采用Server Side Code Exeution。這個方法就非常類似于sql數據庫中存儲過程,將一些常用的sql功能進行封裝,需要時直接調用,會大大減少網絡傳輸的開銷。
另外如使用hint強制使用索引,以及限制limit返回的結果條數這些,都是可選的優化方法。
總結
以上是生活随笔為你收集整理的MongoDB的性能优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kindle资源网址
- 下一篇: linux驱动层获取当前的系统时间