文章出處

前面的話

  本文將詳細介紹MongoDB數據庫索引構建情況分析

  

概述

  創建索引可以加快索引相關的查詢,但是會增加磁盤空間的消耗,降低寫入性能。這時,就需要評判當前索引的構建情況是否合理。有4種方法可以使用

  1、mongostat工具

  2、profile集合介紹

  3、日志

  4、explain分析

 

mongostat

  mongostat是mongodb自帶的狀態檢測工具,在命令行下使用。它會間隔固定時間獲取mongodb的當前運行狀態,并輸出。如果發現數據庫突然變慢或者有其他問題的話,首先就要考慮采用mongostat來查看mongo的狀態

  mongostat是查看mongodb運行狀態的程序,使用方式如下

mongostat -h ip:port

【字段說明】

  insert/s : 每秒插入數據庫的對象數量,如果是slave,則數值前有*,則表示復制集操作
  query/s : 每秒的查詢操作次數
  update/s : 每秒的更新操作次數
  delete/s : 每秒的刪除操作次數
  getmore/s: 每秒查詢cursor(游標)時的getmore操作數
  command: 每秒執行的命令數,在主從系統中會顯示兩個值(例如 3|0),分別代表 本地|復制 命令
  dirty: 臟數據字節的緩存百分比
  used:正在使用中的緩存百分比
  flushes:checkpoint的觸發次數在一個輪詢間隔期間。一般都是0,間斷性會是1, 通過計算兩個1之間的間隔時間,可以大致了解多長時間flush一次。flush開銷是很大的,如果頻繁的flush,可能就要找找原因了
  vsize: 虛擬內存使用量,單位MB 
  res: 物理內存使用量,單位MB。 res會慢慢的上升,如果res經常突然下降,要查看下是否有別的程序狂吃內存
  qr: 客戶端等待從MongoDB實例讀數據的隊列長度
  qw:客戶端等待從MongoDB實例寫入數據的隊列長度
  ar: 執行讀操作的活躍客戶端數量
  aw: 執行寫操作的活客戶端數量。如果ar或aw數值很大,那么就是DB被堵住了,DB的處理速度不及請求速度。查看是否有開銷很大的慢查詢。如果查詢一切正常,確實是負載很大,就需要加機器了
  netIn:MongoDB實例的網絡進流量
  netOut:MongoDB實例的網絡出流量
  conn: 打開連接的總數,是qr,qw,ar,aw的總和
  time:當前時間

【實例】

  插入100000條數據,并打開mongostat查詢mongodb運行狀態

  由下圖看出,插入值insert值在插入數據時大量增加,在插入完畢后變成0。flush兩個1之間的間隔時間很長,說明性能還不錯;res在慢慢上升,沒有出現突然下降的情況,說明沒有其他的程序大量占用內容的情況;qrw及arw數據很小,說明數據庫讀寫狀態正常,負載較小。總體而言,mongodb數據庫運行狀態良好

 

profile

  mongodb可以通過profile來監控數據,進行優化

【級別】

  首先,要查看當前是否開啟profile功能

  使用下面的命令會返回level等級,值為0|1|2,0代表關閉,即不記錄任何操作;1代表記錄慢命令(默認值為100ms),即記錄運行時間超過100ms的操作;2代表全部,即記錄任何操作

db.getProfilingLevel() 

  使用下面的命令可以設置level等級

db.setProfilingLevel() 

  如下圖所示,默認地,profile關閉。使用setProfilingLevel()方法以50ms慢命令的方式開啟profile

【狀態】

  操作被記錄到system.profile集合中

  通過db.system.profile.find() 查看當前的監控日志

op:操作類型
ns:命名空間
query:查詢字符串
responseLength:返回長度
ts:時間
mills:執行耗時

【使用】

  在系統中開啟profile之后,如果profile記錄的數據非常大,會比較明顯的降低系統的性能。因此,profile的使用場景一般是新系統上線之前的測試階段,以及剛上線時的觀察階段,查看數據庫的設計及應用程序的使用是否正常。如果profile記錄了大量的字段,需要調整系統附在、調整索引等,減小它的大小

 

日志

  在配置日志文件時,可以使用verbose參數來配置日志詳細程度,參數值從'v'到'vvvvv','v'越多,詳細度越高

  日志會記錄mongodb的運行狀態,包括連接時間、當前正在進行的操作等

 

explain

  MongoDB 提供了一個 explain 命令讓我們獲知系統如何處理查詢請求。利用 explain 命令,可以很好地觀察系統如何使用索引來加快檢索,同時可以針對性優化索引

  explain有三種模式,分別是:queryPlanner、executionStats、allPlansExecution。現實開發中,常用的是executionStats模式

  首先,插入10萬條數據

  在time字段上建立索引

  接著,尋找time范圍在100和200之間的文檔,并使用explain()

  結果分為queryPlanner、executionStats和serverInfo三個部分。接下來,將分別對這三個部分的結果進行詳細分析

【queryPlanner】

  queryPlanner.plannerVersion: 版本

  queryPlanner.namespace: 查詢的表

  queryPlanner.indexFilterSet: 針對該query是否有indexfilter

  queryPlanner.parsedQuery: 查詢條件

  queryPlanner.winningPlan: 查詢優化器針對該query所返回的最優執行計劃的詳細內容

  queryPlanner.winningPlan.stage: 最優執行計劃的stage

  queryPlanner.winningPlan.inputStage: 用來描述子stage,并且為其父stage提供文檔和索引關鍵字。

  queryPlanner.winningPlan.inputstage.stage,此處是IXSCAN,表示進行的是index scanning

  queryPlanner.winningPlan.inputstage.keyPattern: 索引鍵值對

  queryPlanner.winningPlan.inputstage.indexName:索引名稱

  queryPlanner.winningPlan.inputstage.isMultiKey: 是否是Multikey,此處返回是false,如果索引建立在array上,此處將是true

  queryPlanner.winningPlan.inputstage.direction:查詢順序,此處是forward,如果用了.sort({time:-1})將顯示backward

  queryPlanner.winningPlan.inputstage.indexBounds: 所掃描的索引范圍

  queryPlanner.rejectedPlans:其他執行計劃

【executionStats】

  executionStats.executionSuccess: 是否成功

  executionStats.nReturned: 查詢返回條目個數

  executionStats.totalKeysExamined: 索引掃描條目個數

  executionStats.totalDocsExamined: 文檔掃描條目個數

  executionStats.executionStages.stage: 掃描類型

  executionStats.executionTimeMillis: 整體查詢時間

  executionStats.executionStages.executionTimeMillisEstimate: 根據索引檢索文檔獲得數據的時間

  executionStats.executionStages.inputStage.executionTimeMillisEstimate: 掃描索引所用時間

【serverInfo】

  serverInfo.host: 主機名

  serverInfo.port: 端口

  serverInfo.version: 版本

  serverInfo.gitVersion: git版本

【性能分析】

  1、執行時間

  executionTimeMillis值越小越好

  2、條目數量

  最理想的狀態是:  nReturned=totalKeysExamined=totalDocsExamined

  3、stage類型

  stage的類型列舉如下:

COLLSCAN:全表掃描
IXSCAN:索引掃描
FETCH:根據索引去檢索指定document
SHARD_MERGE:將各個分片返回數據進行merge
SORT:表明在內存中進行了排序
LIMIT:使用limit限制返回數
SKIP:使用skip進行跳過
IDHACK:針對_id進行查詢
SHARDING_FILTER:通過mongos對分片數據進行查詢
COUNT:利用db.coll.explain().count()之類進行count運算
COUNTSCAN:count不使用Index進行count時的stage返回
COUNT_SCAN:count使用了Index進行count時的stage返回
SUBPLA:未使用到索引的$or查詢的stage返回
TEXT:使用全文索引進行查詢時候的stage返回
PROJECTION:限定返回字段時候stage的返回

  不希望看到包含如下的stage:

COLLSCAN(全表掃描)
SORT(使用sort但是無index)
不合理的SKIP
SUBPLA(未用到index的$or) COUNTSCAN(不使用index進行count)

 


文章列表


不含病毒。www.avast.com
全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣()