设为首页 收藏本站
查看: 1485|回复: 0

[经验分享] MongoDB数据库索引构建情况分析

[复制链接]

尚未签到

发表于 2017-12-15 06:59:56 | 显示全部楼层 |阅读模式
前面的话
  本文将详细介绍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运行状态

DSC0000.png   由下图看出,插入值insert值在插入数据时大量增加,在插入完毕后变成0。flush两个1之间的间隔时间很长,说明性能还不错;res在慢慢上升,没有出现突然下降的情况,说明没有其他的程序大量占用内容的情况;qrw及arw数据很小,说明数据库读写状态正常,负载较小。总体而言,mongodb数据库运行状态良好

DSC0001.png
profile
  mongodb可以通过profile来监控数据,进行优化
  【级别】
  首先,要查看当前是否开启profile功能
  使用下面的命令会返回level等级,值为0|1|2,0代表关闭,即不记录任何操作;1代表记录慢命令(默认值为100ms),即记录运行时间超过100ms的操作;2代表全部,即记录任何操作
  

db.getProfilingLevel()   

  使用下面的命令可以设置level等级
  

db.setProfilingLevel()   

  如下图所示,默认地,profile关闭。使用setProfilingLevel()方法以50ms慢命令的方式开启profile

DSC0002.png   【状态】
  操作被记录到system.profile集合中

DSC0003.png   通过db.system.profile.find() 查看当前的监控日志

DSC0004.png
DSC0005.png   

op:操作类型  
ns:命名空间
  
query:查询字符串
  
responseLength:返回长度
  
ts:时间
  
mills:执行耗时
  

  【使用】
  在系统中开启profile之后,如果profile记录的数据非常大,会比较明显的降低系统的性能。因此,profile的使用场景一般是新系统上线之前的测试阶段,以及刚上线时的观察阶段,查看数据库的设计及应用程序的使用是否正常。如果profile记录了大量的字段,需要调整系统附在、调整索引等,减小它的大小

日志
  在配置日志文件时,可以使用verbose参数来配置日志详细程度,参数值从'v'到'vvvvv','v'越多,详细度越高
  日志会记录mongodb的运行状态,包括连接时间、当前正在进行的操作等

DSC0006.png
explain
  MongoDB 提供了一个 explain 命令让我们获知系统如何处理查询请求。利用 explain 命令,可以很好地观察系统如何使用索引来加快检索,同时可以针对性优化索引
  explain有三种模式,分别是:queryPlanner、executionStats、allPlansExecution。现实开发中,常用的是executionStats模式
  首先,插入10万条数据

DSC0007.png   在time字段上建立索引

DSC0008.png   接着,寻找time范围在100和200之间的文档,并使用explain()
  结果分为queryPlanner、executionStats和serverInfo三个部分。接下来,将分别对这三个部分的结果进行详细分析
  【queryPlanner】

DSC0009.png   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】

DSC00010.png   executionStats.executionSuccess: 是否成功
  executionStats.nReturned: 查询返回条目个数
  executionStats.totalKeysExamined: 索引扫描条目个数
  executionStats.totalDocsExamined: 文档扫描条目个数
  executionStats.executionStages.stage: 扫描类型
  executionStats.executionTimeMillis: 整体查询时间
  executionStats.executionStages.executionTimeMillisEstimate: 根据索引检索文档获得数据的时间
  executionStats.executionStages.inputStage.executionTimeMillisEstimate: 扫描索引所用时间
  【serverInfo】

DSC00011.png   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)
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-424234-1-1.html 上篇帖子: 【数据库】Mean web开发 03-MongoDB客户端管理工具NoSQL Manager for MongoDB的使用 下篇帖子: nodejs+express+mongodb搭建博客
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表