MongoDB&C++开发 (七)【转】 MongoDB性能分析

有分析MongoDB性能的需求(主要是插入和查询),查阅资料总结如下。
摘自:
MongoDB与MySQL的插入查询性能测试 CSDN博客

1.MongoDB与MySQL的插入查询性能测试

1.1 机器配置&数据规模

数据规模设定在1亿条。
机器配置: CPU:Intel(R) Xeon(R) CPU E5-2620 @ 2.00GHz
内存:65954040 KB (12核CPU,64G内存)
操作系统: Linux version 2.6.32_1-8-0-0 (gcc version 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC) )
MongoDB版本: 2.2.3,无任何优化配置,单机测试
MySQL版本: 5.1.49,无任何优化配置,单机测试
测试语言: Python 2.7.1
数据库接口驱动:
MongoDB : PyMongo 2.1.1
MySQL: MySQLdb 1.2.3

1.2 测试方法

先在内存中生成1亿条数据后,再执行插入操作的。还好测试机器的内存足够大,能够存下如此多的数据。
以如下四种模式向数据库中插入数据,每插1000条数据时,就往一个固定的文件中写入该时刻的时间:

a) 在MongoDB中指定_id为1 – 100,000,000 的md5值,将数据插入;

b) 在MongoDB中不指定_id值,将1 – 100,000,000 的md5值视为普通的字段插入;

c) 在MySQL中以1 – 100,000,000 的md5值为PRIMARY KEY,将数据插入;

d) 在MySQL中不指定PRIMARY KEY,将1 – 100,000,000 的md5值视为普通的字段插入。
根据生成的时间文件记录,分析MySQL与MongoDB的插入性能。

1.3 插入测试结果

  1. 数据库的平均插入速率:MongoDB不指定_id插入 > MySQL不指定主键插入 > MySQL指定主键插入 > MongoDB指定_id插入。
  2. MongoDB在指定_id与不指定_id插入时速度相差很大,而MySQL的差别却小很多。
    纵坐标单位是秒,横坐标表示每1000条数据的插入时间,最快的是MongoDB不指定_id插入,时间大概为0.07秒/1000条
    也就是7秒/10万条,70秒/百万条。
    这里写图片描述
结论:
  1. 在指定_id或主键时,两种数据库在插入时要对索引值进行处理,并查找数据库中是否存在相同的键值,这会减慢插入的速率。

  2. 在MongoDB中,指定索引插入比不指定慢很多,这是因为,MongoDB里每一条数据的_id值都是唯一的。当在不指定_id插入数据的时候,其_id是系统自动计算生成的。MongoDB通过计算机特征值、时间、进程ID与随机数来确保生成的_id是唯一的。而在指定_id插入时,MongoDB每插一条数据,都需要检查此_id可不可用,当数据库中数据条数太多的时候,这一步的查询开销会拖慢整个数据库的插入速度。

  3. MongoDB会充分使用系统内存作为缓存,这是一种非常优秀的特性。我们的测试机的内存有64G,在插入时,MongoDB会尽可能地在内存快写不进去数据之后,再将数据持久化保存到硬盘上。这也是在不指定_id插入的时候,MongoDB的效率遥遥领先的原因。但在指定_id插入时,当数据量一大内存装不下时,MongoDB就需要将磁盘中的信息读取到内存中来查重,这样一来其插入效率反而慢了。

  4. MySQL不愧是一种非常稳定的数据库,无论在指定主键还是在不指定主键插入的情况下,其效率都差不了太多。

1.4 读取测试结果

测试方法:

先在1 – 100, 000, 000这一亿个数中,分别随机取1w, 5w, 10w, 20w, 50w个互不相同的数字,再计算其md5值,并保存。
至于为什么最高只选到50w这个规模,这是因为我在随机生成100w个互不相同的数字的时候,写的脚本跑了一晚上都没有跑出来,估计是我生成的算法写得太烂了。我不想重新再弄了,暂就以50w为上限吧。
在上述带主键插入的两个数据库里,分别以上一步生成的md5源为输入进行查询操作。同样,每查询1000条数据在日志文件中将当前系统时间写入。

横坐标为查询规模,共有5个等级,纵坐标时间为秒,表示每查询1000条数据所需要的时间。
这里写图片描述
这里写图片描述
对比一下:
这里写图片描述

结论:
  1. 如果MySQL没有经过查询优化的话,其查询速度就不要跟MongoDB比了。MongoDB可以充分利用系统的内存资源,我们的测试机器内存是64GB的,内存越大MongoDB的查询速度就越快,毕竟磁盘与内存的I/O效率不是一个量级的。
  2. 本次实验的查询的数据也是随机生成的,因此所有待查询的数据都存在MongoDB的内存缓存中的概率是很小的。在查询时,MongoDB需要多次将内存中的数据与磁盘进行交互以便查找,因此其查询速率取决于其交互的次数。这样就存在这样一种可能性,尽管待查询的数据数目较多,但这段随机生成的数据被MongoDB以较少的次数从磁盘中取出。因此,其查询的平均速度反而更快一些。这样看来,MongoDB的查询速度波动也处在一个合理的范围内。
  3. MySQL的稳定性还是毋庸置疑的。
  4. 相比较MySQL,MongoDB数据库更适合那些读作业较重的任务模型。MongoDB能充分利用机器的内存资源。如果机器的内存资源丰富的话,MongoDB的查询效率会快很多。
  5. 在带”_id”插入数据的时候,MongoDB的插入效率其实并不高。如果想充分利用MongoDB性能的话,推荐采取不带”_id”的插入方式,然后对相关字段作索引来查询。

2.提升MongoDB性能的方法

来源: Mongodb性能调优 -性能优化建议 CSDN博客
1. 建索引!!!在查询排序统计等的条件上建立索引,也可考虑复合索引。结合实际情况正确使用索引方向(逆序或正序),使用limit()限定返回结果集的大小,减少资源损耗。
2. 只查询使用到的字段而不是所有字段。
3. 基于MongoDB分布式集群做数据分析时,MapReduce性能优于count、distinct、group等聚合函数。
4. Capped Collections比普通Collections的读写效率高 。
5. Mongodb 3.0.X版本性能较Mongodb 2.0.X有7-10倍提升,引入WiredTiger新引擎,同时支持MMAPv1内存映射引擎。
6.设计数据库的时候,应考虑主要是做查询还是做插入还是做其他操作,进行范式化设计,反范式化设计还是不完全范式化设计。
范式化设计的思想是“完全分离”,存在关联查询,查询效率低,但写入、修改、删除性能更高
反范式化设计的思想是“数据集中存储”,查询效率高,而MongoDB对查询机制支持较弱,看似成为一种互补。
例:

//范式化设计
{
     "_id" : ObjectId("5124b5d86041c7dca81917"),
     "title" : "MongoDB性能调优", 
      "author" : [ 
               ObjectId("144b5d83041c7dca84416"),
              ObjectId("144b5d83041c7dca84418"),
              ObjectId("144b5d83041c7dca84420"),
     ]
 } 
//反范式化设计
{
       "_id" : ObjectId("5124b5d86041c7dca81917"),
       "title" : "MongoDB性能调优",
       "author" : [
                {
                         "name" : "张三"
                         "age" : 40,
                         "nationality" : "china",
                },
                {
                         "name" : "李四"
                         "age" : 49,
                         "nationality" : "china",
                },
                {
                         "name" : "王五"
                         "age" : 59,
                         "nationality" : "china",
                },
      ]
}
//不完全范式化设计
{
       "_id" : ObjectId("5124b5d86041c7dca81917"),
       "title" : "MongoDB性能调优",
       "author" : [ 
               {
                         "_id" : ObjectId("144b5d83041c7dca84416"),
                         "name" : "张三"
                },
                {
                         "_id" : ObjectId("144b5d83041c7dca84418"),
                         "name" : "李四"
                },
                {
                         "_id" : ObjectId("144b5d83041c7dca84420"),
                         "name" : "王五"
                },
      ]
  }
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值