wiredTigerlinux
MongoDB從3.0開始引入可插拔存儲引擎的概念。目前主要有MMAPV一、WiredTiger存儲引擎可供選擇。在3.2版本以前MMAPV1是默認的存儲引擎,其採用linux操做系統內存映射技術,但一直飽受詬病;3.4以上版本默認的存儲引擎是wiredTiger,相對於MMAPV1其有以下優點:算法
讀寫操做性能更好,WiredTiger能更好的發揮多核系統的處理能力;
MMAPV1引擎使用表級鎖,當某個單表上有併發的操做,吞吐將受到限制。WiredTiger使用文檔級鎖,由此帶來併發及吞吐的提升
相比MMAPV1存儲索引時WiredTiger使用前綴壓縮,更節省對內存空間的損耗;
提供壓縮算法,能夠大大下降對硬盤資源的消耗,節省約60%以上的硬盤資源;mongodb
mongodb數據會丟失?你須要瞭解WT寫入的原理數據庫
Journaling相似於關係數據庫中的事務日誌。Journaling可以使MongoDB數據庫因爲意外故障後快速恢復。MongoDB2.4版本後默認開啓了Journaling日誌功能,mongod實例每次啓動時都會檢查journal日誌文件看是否須要恢復。因爲提交journal日誌會產生寫入阻塞,因此它對寫入的操做有性能影響,但對於讀沒有影響。在生產環境中開啓Journaling是頗有必要的。數組
寫策略解析服務器
配置文件併發
storage: journal: enabled: true dbPath: /data/zhou/mongo1/ ##是否一個庫一個文件夾 directoryPerDB: true ##數據引擎 engine: wiredTiger ##WT引擎配置 WiredTiger: engineConfig: ##WT最大使用cache(根據服務器實際狀況調節) cacheSizeGB: 1 ##是否將索引也按數據庫名單獨存儲 directoryForIndexes: true journalCompressor:none (默認snappy) ##表壓縮配置 collectionConfig: blockCompressor: zlib (默認snappy,還可選none、zlib) ##索引配置 indexConfig: prefixCompression: true
壓縮 算法 Tips:
性能: none > snappy >zlib
壓縮比:zlib > snappy > noneapp
索引命令概要與類型函數
索引一般可以極大的提升查詢的效率,若是沒有索引,MongoDB在讀取數據時必須掃描集合中的每一個文件並選取那些符合查詢條件的記錄。索引主要用於排序和檢索性能
單鍵索引
在某一個特定的屬性上創建索引,例如:db.users. createIndex({age:-1});
mongoDB在ID上創建了惟一的單鍵索引,因此常常會使用id來進行查詢;
在索引字段上進行精確匹配、排序以及範圍查找都會使用此索引;
複合索引
在多個特定的屬性上創建索引,例如:db.users. createIndex({username:1,age:-1,country:1});
複合索引鍵的排序順序,能夠肯定該索引是否能夠支持排序操做;
在索引字段上進行精確匹配、排序以及範圍查找都會使用此索引,但與索引的順序有關;
爲了性能考慮,應刪除存在與第一個鍵相同的單鍵索引
多鍵索引
在數組的屬性上創建索引,例如:db.users. createIndex({favorites.city:1});針對這個數組的任意值
的查詢都會定位到這個文檔,既多個索引入口或者鍵值引用同一個文檔
哈希索引
不一樣於傳統的B-樹索引,哈希索引使用hash函數來建立索引。
例如:db.users. createIndex({username : 'hashed'});
在索引字段上進行精確匹配,但不支持範圍查詢,不支持多鍵hash;
Hash索引上的入口是均勻分佈的,在分片集合中很是有用;
索引語法
MongoDB使用 ensureIndex() 方法來建立索引,ensureIndex()方法基本語法格式以下所示:
db.collection.createIndex(keys, options)
語法中 Key 值爲要建立的索引字段,1爲指定按升序建立索引,若是你想按降序來建立索引指定爲-1,也能夠指定爲hashed(哈希索引)。
語法中options爲索引的屬性,屬性說明見下表;
建立索引
單鍵惟一索引:db.users. createIndex({username :1},{unique:true});
單鍵惟一稀疏索引:db.users. createIndex({username :1},{unique:true,sparse:true});
複合惟一稀疏索引:db.users. createIndex({username:1,age:-1},{unique:true,sparse:true});
建立哈希索引並後臺運行:db.users. createIndex({username :'hashed'},{background:true});
刪除索引
根據索引名字刪除某一個指定索引:db.users.dropIndex("username_1");
刪除某集合上全部索引:db.users.dropIndexs();
重建某集合上全部索引:db.users.reIndex();
查詢集合上全部索引:db.users.getIndexes();
查詢優化技巧 第一步
找出慢速查詢
開啓內置的查詢分析器,記錄讀寫操做效率:
db.setProfilingLevel(n,{m}),n的取值可選0,1,2;
0是默認值表示不記錄;
1表示記錄慢速操做,若是值爲1,m必須賦值單位爲ms,用於定義慢速查詢時間的閾值;
2表示記錄全部的讀寫操做;
例如:db.setProfilingLevel(1,300)
查詢監控結果
監控結果保存在一個特殊的蓋子集合system.profile裏,這個集合分配了128kb的空間,要確保監控分析數據不會消耗太多的系統性資源;蓋子集合維護了天然的插入順序,可使用$natural操做符進行排序,如:db.system.profile.find().sort({'$natural':-1}).limit(5)
查詢優化技巧 第二步
分析慢速查詢
找出慢速查詢的緣由比較棘手,緣由可能有多個:應用程序設計不合理、不正確的數據模型、硬件配置問題,缺乏索引等;接下來對於缺乏索引的狀況進行分析:
使用explain分析慢速查詢
例如:db.orders.find({'price':{'$lt':2000}}).explain('executionStats')
explain的入參可選值爲:
"queryPlanner" 是默認值,表示僅僅展現執行計劃信息;
"executionStats" 表示展現執行計劃信息同時展現被選中的執行計劃的執行狀況信息;
"allPlansExecution" 表示展現執行計劃信息,並展現被選中的執行計劃的執行狀況信息,還展現備選的執行計劃的執行狀況信息;
查詢優化技巧 第三步
解讀explain結果
queryPlanner(執行計劃描述)
winningPlan(被選中的執行計劃)
stage(可選項:COLLSCAN 沒有走索引;IXSCAN使用了索引)
rejectedPlans(候選的執行計劃)
executionStats(執行狀況描述)
nReturned (返回的文檔個數)
executionTimeMillis(執行時間ms)
totalKeysExamined (檢查的索引鍵值個數)
totalDocsExamined (檢查的文檔個數)
優化目標 Tips:
1. 根據需求創建索引
2. 每一個查詢都要使用索引以提升查詢效率, winningPlan. stage 必須爲IXSCAN ;
3. 追求totalDocsExamined = nReturned
關於索引的建議
1. 索引頗有用,可是它也是有成本的——它佔內存,讓寫入變慢; 2. mongoDB一般在一次查詢裏使用一個索引,因此多個字段的查詢或者排序須要複合索引才能更加高效; 3. 複合索引的順序很是重要 4. 在生成環境構建索引每每開銷很大,時間也不能夠接受,在數據量龐大以前儘可能進行查詢優化和構建索引; 5. 避免昂貴的查詢,使用查詢分析器記錄那些開銷很大的查詢便於問題排查; 6. 經過減小掃描文檔數量來優化查詢,使用explai對開銷大的查詢進行分析並優化; 7. 索引是用來查詢小範圍數據的,不適合使用索引的狀況: 每次查詢都須要返回大部分數據的文檔,避免使用索引 寫比讀多