Mongodb VS Mysql 查询性能

来源:互联网 发布:帝国cms 数据备份目录 编辑:程序博客网 时间:2024/05/16 17:34

Mongodb VS Mysql 查询性能

转自:http://www.wdcode.org/archives/452.html

最近想用 Mongodb 做些存储层的事情。目前主要用在 id 查询或 ids 查询(如 mysql 的 in 查询)。新的方案能否上线还要看性能。现在把  mongodb 与 mysql 来对比下。

环境:同一台机器,装有 mongodb 1.4, mysql;内存 4g;两个数据库都只有 id 的唯一搜索;数据量 120w 左右,5w  个查询。对它们进行 id 或 ids 查询。

 

 mongodbmysqltotal timeavg time/per querytotal timeavg time/per query1 id/per query11954ms, 00:11,9540ms, 00,078613ms, 00:1:18,6131ms, 00,110 id/per query35885ms, 00:35,8850ms, 00,0107274ms, 00:1:47,2742ms, 00,220 id/per query63714ms, 00:1:3,7141ms, 00,1186398ms, 00:3:6,3983ms, 00,35 thread, 20 id/per query-5ms, 00,5-11ms, 00,1110 thread, 20 id/per query-10ms, 00,10-22ms, 00,22

 

从上表看:

每次查一个 id 的查询,在基本相同条件下 mongodb 速度是 mysql 的 7 倍。

每次查多个 id (10/20)的查询,mongodb 比 mysql 快 2 倍。

多线程下查多个 id,mongodb 比 mysql 快 1 倍。

从上面的测试来看:主要用在 id 查询或 ids 查询的应用中 mongodb 要优越 mysql。

在插入这些数据的时候,mongodb 更加快于 mysql,插入120w 到 mongodb 用 83159ms, ->00:1:23,159  就够了。mysql 有几十分钟。

当我在实际应用中(kw 级数据量),使用 mongodb 速度没有 mysql 好。原因可能有,mysql 的机器好,mongodb  使用不够得当。继续调整和优化程序吧……

附 mongodb 的 in 查询:

代码

1

2         BasicDBObject q = new BasicDBObject();

3

4         BasicDBObject in = new BasicDBObject();

5

6

7

8         void createQ(Integer[] ids) {

9

10          q.put(“id”, in);

11

12          in.put(“$in”, ids);

13

14      }

 

 

上一篇:Mongodb VS Mysql 查询性能,测试了 mongodb 与 mysql 的查询性能。结果说明 mongodb 性能可以, 可以代替 mysql 来使用。

但是这个测试都是在百万级别,我的场景在 KW 级别。所以还要对 mongodb 在 kw 级别下测试效果。

我测试环境是 4G 内存(有好些内存被其它程序占用),2kw 数据,查询随机生成 id(一次查询 20 个id)。

在这样的环境中测试不理想,比较失望。平均一次查询 500ms(比 mysql 还差,特别是在并发查询下,性能较差。很底的吞吐量)。查看其索引大小(用 db.mycoll.stats() 可以查询):2kw 数据中有 1.1G 左右的索引,存储的数据在 11G 左右。

测试过程中发现 iowait 占 50% 左右,看来还是 io 的瓶颈。还看到 mongodb 使用的内存不多(小于索引的大小,看来这机器不足够来测试)。

换了个有可用 6G 内存的机器。在 50 个并发下,可以达到平均 100 ms 左右,算比较满意,但是并发好像能力不够强。但这个性能不能由我控制,还由机器的可用内存控制。原因就是 mongodb 没有指定可占用的内存大小,它把所有空闲内存当缓存使用,既是优点也是缺点:优点–可以最大限度提升性能;缺点–容易受其它程序干扰(占用了它的缓存)。由我测试来看,它抢占内存的能力不强。mongodb 是用内存映射文件 vmm,官方的说明:

Memory Mapped Storage Engine

This is the current storage engine for MongoDB, and it uses memory-mapped files for all disk I/O. Using this strategy, the operating system’s virtual memory manager is in charge of caching. This has several implications:

  • There is no redundancy between file system cache and database cache: they are one and the same.
  • MongoDB can use all free memory on the server for cache space automatically without any configuration of a cache size.
  • Virtual memory size and resident size will appear to be very large for the mongod process. This is benign: virtual memory space will be just larger than the size of the datafiles open and mapped; resident size will vary depending on the amount of memory not used by other processes on the machine.
  • Caching behavior (such as LRU’ing out of pages, and laziness of page writes) is controlled by the operating system: quality of the VMM implementation will vary by OS.

所以这么来看,我觉得 mongodb 没有指定内存大小来保证正常的缓存是个缺点。应该至少保证索引全部能放到内存中。但这个行为不是由启动程序决定,而是由环境决定(美中不足)。

官方也有段内容说到索引放到内存中:

If your queries seem sluggish, you should verify that your indexes are small enough to fit in RAM. For instance, if you’re running on 4GB RAM and you have 3GB of indexes, then your indexes probably aren’t fitting in RAM. You may need to add RAM and/or verify that all the indexes you’ve created are actually being used.

还是希望 mongodb 中可以指定内存大小,确保它有足够内存加载索引。

小结:大数据量下(kw级)mongodb 并发查询不够理想(100-200/s)。写数据很快(我的环境,远程提交近 1w/s,估计达到 1.5W/s 是没问题的,基本不受大数据量的影响)。

贴个测试数据:

 

 1 id(内存使用 <1.5g)10 id(内存使用 2-3g)20 id(内存使用 >4g) 123123123total time17.13625.50817.38737.13833.78825.14344.7531.16730.6781 thread thruput583.5668392.0339575.1423269.266295.9631397.725223.4637320.8522325.9665          total time24.40522.66424.11541.45441.88939.74956.13853.71354.6665 thread thruput2048.762206.1422073.3981206.1561193.6311257.893890.6623930.8733914.6453          total time27.56726.86728.34955.67254.34750.9372.97881.85775.92510 thread thruput3627.5263722.0383527.4611796.2351840.0281963.4791370.2761221.6431317.089          total time51.39757.44653.81119.386118.01576.405188.962188.034138.83920 thread thruput3891.2783481.533716.7811675.2381694.72617.631058.4141063.6371440.517          total time160.038160.808160.346343.559352.732460.678610.907609.9861411.30650 thread thruput3124.2583109.2983118.2571455.3541417.5071085.357818.4552819.6909354.2818          total time2165.408635.887592.9581090.2641034.0571060.2661432.2961466.9711475.061100 thread thruput461.80671572.6061686.46917.209967.0647943.1595698.1797681.6767677.9381          

上面的测试分别用三种查询(每次 1,10,20 id),在不同并发下测试3次,每次发出 1w 次查询。第一行数据为所有线程累加时间(单位 ms),第二行数据为吞吐量(1w /(total time / thread num))。测试中内存使用慢慢增加,所以后面的数据可能比较高效的(高效的环境)。

从上表看,10 – 20线程比较高的吞吐量。看到内存使用,前提就是索引加载到内存中,并有些内存作为缓存。

下面有个索引查询优化的 pdf。

Indexing and Query Optimizer

Indexing and Query Optimizer (Aaron Staple)

ps:

默认 mongodb 服务器只有10个并发,如果要提高它的连接数,可以用 –maxConns num 来提高它的接收并发的数据。

mongodb 的 java 驱动默认最多只有 10 并发连接池。要提高它,可以在 mongo.jar 的环境中加入 MONGO.POOLSIZE 系统参数,如 java -DMONGO.POOLSIZE=50



原创粉丝点击