说到数据库方面的优化,我们首先想到的是利用索引技术,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分析数据查询示例:

//1.执行时间大于5毫秒的操作信息:
>db.system.profile.find( { millis : { $gt : 5 } } ).pretty()//2.某一时间段的操作执行信息:
>db.system.profile.find({ts : {$gt : new ISODate("2016-06-17T03:00:00Z") ,$lt : new ISODate("2016-06-17T03:40:00Z")}}).pretty()//3.在某一时间段,某一用户执行信息并对每一次操作执行所消耗的时间进行排序:
>db.system.profile.find({ts : {$gt : new ISODate("2016-06-17T03:00:00Z") ,$lt : new ISODate("2016-06-17T03:40:00Z")}},{ user : 0 }).sort( { millis : -1 } )

当开启优化器profiler,其实只会对系统性能产生较小的效果。system.profile是一个默认大小为1M的capped collection集合,这样大小的集合通常可以存储数千的profile文档数据,但是有一些应用程序每执行一次操作,可能会产生更多或者更少的分析数据。

如何改变system.profile集合的大小?
例如,你需要创建一个400000bytes的system.profile集合,在mongo脚本执行以下命令:

//1.关闭优化器
>db.setProfilingLevel(0)//2.删除system.profile
>db.system.profile.drop()//3.创建一个新的system.profile集合
>db.createCollection( "system.profile", { capped: true, size:4000000 } )//4.重启优化器
>db.setProfilingLevel(1)

三:性能优化总结

方法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的性能优化相关推荐

  1. mysql mongodb 秒杀_绝赞!B站投币20W+的Redis/MongoDB/Mysql性能优化宝藏库,我先磕了

    性能优化算是老生常谈的话题了,不管项目大小,一旦上线,或多或少都会遇到性能问题.有些性能问题是随着时间的积累慢慢产生的,比如系统刚上线,数据量很小的时候,没啥问题,等到数据积累到一定程度,问题就暴露出 ...

  2. MongoDB 教程五: MongoDB固定集合和性能优化 (索引Indexes, 优化器, 慢查询profile)

    mongodb索引详解(Indexes) 索引介绍 索引在mongodb中被支持,如果没有索引,mongodb必须扫描每一个文档集合选择匹配的查询记录.这样扫描集合效率并不高,因为它需要mongod进 ...

  3. MongoDB 教程五: MongoDB固定集合和性能优化

    MongoDB 固定集合(Capped Collections) MongoDB 固定集合(Capped Collections)是性能出色且有着固定大小的集合,对于大小固定,我们可以想象其就像一个环 ...

  4. MongoDB学习笔记(四)--索引 性能优化

    索引                                                                                             基础索引 ...

  5. mongodb性能优化

    一.范式化与反范式化 范式的优点: 1)范式化的数据库更新起来更加快: 2)范式化之后,只有很少的重复数据,只需要修改更少的数据: 3)范式化的表更小,可以在内存中执行: 4)很少的冗余数据,在查询的 ...

  6. 速递!MongoDB最新书籍出版啦:MongoDB进阶与实战-微服务整合、性能优化、架构管理

    新书速递 近期,MongoDB中文社区核心成员之一唐卓章老师出了一本MongoDB最新书籍--<MongoDB进阶与实战:微服务整合.性能优化.架构管理>,全面涵盖了MongoDB的基本原 ...

  7. mongodb聚合查询优化_【MongoDB】MongoDB 性能优化 - BI查询聚合

    最全的Java后端知识体系每天更新中.... 在BI服务中通过查询聚合语句分析定位慢查询/聚合分析,小结如下: 慢查询定位: 通过Profile分析慢查询 对于查询优化: 通过添加相应索引提升查询速度 ...

  8. mongodb线程池_常用高并发网络线程模型设计及MongoDB线程模型优化实践

    服务端通常需要支持高并发业务访问,如何设计优秀的服务端网络IO工作线程/进程模型对业务的高并发访问需求起着至关重要的核心作用. 本文总结了了不同场景下的多种网络IO线程/进程模型,并给出了各种模型的优 ...

  9. ensp大型网络环境设计与实现_mongodb内核源码设计实现、性能优化、最佳运维系列-网络传输层模块源码实现三...

    1. 说明 在之前的<<Mongodb网络传输处理源码实现及性能调优-体验内核性能极致设计>>和<<mongodb内核源码设计实现.性能优化.最佳运维系列-tran ...

  10. 项目实践中的一些性能优化指南

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:xybaby cnblogs.com/xybaby/p/90 ...

最新文章

  1. OMG:为什么用了索引,查询还是慢?
  2. java自定义注解为空值_java自定义注解
  3. 从JavaScript函数重名看其初始化方式
  4. HEVC流媒体服务器被过度炒作的5个原因
  5. 153. 寻找旋转排序数组中的最小值 golang
  6. VC.NET字符指针与String的转换
  7. LEADTOOLS Multimedia SDK更新:改进RTSP和H.265/H.264的硬件加速
  8. 在html中控制自动换行
  9. linux进程控制-exit()
  10. 区块链教程Fabric1.0源代码分析Ledger statedb(状态数据库)
  11. 什么时候以及为什么基于树的模型可以超过神经网络模型?
  12. Openstack(十四)创建虚拟机
  13. Java基础知识强化之集合框架笔记15:List集合的特点
  14. 精通innodb引擎_《MySQL技术内幕:InnoDB存储引擎》PDF 下载
  15. WordPress中文插件 Erphpdown vip会员+推广提成+收费下载/查看内容+前端个人中心 银联/支付宝/微信支付/财付通/贝宝paypal[更新至v9.6.1]
  16. devexpress控件使用笔记
  17. 达梦 DCA 培训总结
  18. 【基于LM358和LM386的话音放大器设计】
  19. 【学习体会】Lighttools8.4.0:简单光学系统实例
  20. 青海打造农畜产品“全域绿色” 化肥农药将减量20%以上

热门文章

  1. Db4o数据库:细说查询
  2. linux终端字体安装,在Gnome-terminal下安装以及使用Monaco字体
  3. 频谱仪测试gsm信号测试软件,怎样用频谱分析仪测试和分析GSM信号
  4. 土豆系统 Ghost xp3 装机版
  5. Android Java 颜色代码 对照表
  6. 从零开始系统学习区块链
  7. 【Unity Native Plugins】1.调用动态库so-android篇 附录完整工程
  8. android studio简单的密码日记本,实现增删改查功能
  9. linux 16.04系统下载,【ubuntu16.04】ubuntu(乌班图系统)镜像文件下载 v16.04 稳定版本-七喜软件园...
  10. python微信语音转发方法_微信语音转发最方便的方法,我现在才知道