Mongodb Mysql 小测试 (To Be Continued)

来源:互联网 发布:怎么破解软件 编辑:程序博客网 时间:2024/06/08 06:50

mongo-vs-mysql

尝试测试Mongodb 和 Mysql的性能,测试/数据导入代码:github: mongo-vs-mysql

性能比较很复杂,不能简单就说谁的性能高,谁的低。要基于场景,基于并发请求数量来谈,同时也要知道如何调优,本文只是初探,在没有任何调优的基础上,在本地windows 7上进行测试。

版本及环境

  • 操作系统: windows 7
  • 硬件环境: (只做对比,mongodb和mysql都装在同一台机器上)
  • mongodb: 3.2.5
  • mysql: 5.7

Data-demo

Data-demo 是一个Spring Boot的项目, 通过Spring Boot的CommandLineRunner来批量动态插入1000,020 条数据。

数据结构采用常用的产品和类目的多对多的设计。
这里写图片描述

Category 数据如下:

id code name ‘1’ ‘cate-1’ ‘Category 1’ ‘2’ ‘cate-2’ ‘Category 2’ ‘3’ ‘cate-3’ ‘Category 3’ ‘4’ ‘cate-4’ ‘Category 4’

Product 数据如下

id code name price ‘1’ ‘p-0’ ‘product 0’ ‘19’ ‘2’ ‘p-1’ ‘product 1’ ‘19’ ‘3’ ‘p-2’ ‘product 2’ ‘19’ … … … … ‘1000000’ ‘p-999999’ ‘product 999999’ ‘19’ ‘1000001’ ‘pp-0’ ‘iphone’ ‘19’ ‘1000002’ ‘pp-1’ ‘iphone’ ‘19’ ‘1000003’ ‘pp-2’ ‘iphone’ ‘19’ ‘1000004’ ‘pp-3’ ‘iphone’ ‘19’ ‘1000005’ ‘pp-4’ ‘iphone’ ‘19’ ‘1000006’ ‘pp-5’ ‘iphone’ ‘19’ ‘1000007’ ‘pp-6’ ‘iphone’ ‘19’ ‘1000008’ ‘pp-7’ ‘iphone’ ‘19’ ‘1000009’ ‘pp-8’ ‘iphone’ ‘19’ ‘1000010’ ‘pp-9’ ‘iphone’ ‘19’ ‘1000011’ ‘pp-10’ ‘iphone’ ‘19’ ‘1000012’ ‘pp-11’ ‘iphone’ ‘19’ ‘1000013’ ‘pp-12’ ‘iphone’ ‘19’ ‘1000014’ ‘pp-13’ ‘iphone’ ‘19’ ‘1000015’ ‘pp-14’ ‘iphone’ ‘19’ ‘1000016’ ‘pp-15’ ‘iphone’ ‘19’ ‘1000017’ ‘pp-16’ ‘iphone’ ‘19’ ‘1000018’ ‘pp-17’ ‘iphone’ ‘19’ ‘1000019’ ‘pp-18’ ‘iphone’ ‘19’ ‘1000020’ ‘pp-19’ ‘iphone’ ‘19’

最后的二十行是用来方便查询验证的。

Product_Category

中间mapping的表格

Mongo 数据

采用了 Nodejs+express+mongoose 来导入mongo的数据. 项目express-mongoose-microservice-api-boilerplate中的config/test.env来配置mongo的数据库地址。npm install 然后运行命令npm run produceTestData 可以初始化1000,020 条产品数据到mongodb。 数据类似mysql的产品数据:

产品 Product

{    "_id": "59cb4952d44efa2eb45d4bf7",    "code": "p-0",    "name": "Product 0",    "price": 19,    "__v": 0,    "categories": [        "cate-1",        "cate-2"    ]}

有20条产品数据的categories中有cate-4

通过查询脚本直接测试:

通过Robomongo 连接Mongodb来测试,通过mysql的workbench来完成mysql的脚本查询。

场景一:查询单个类目下的产品

mongo 查询所有的cate-4 的产品

db.getCollection('products').find({categories:'cate-4'}) // 初次查询1.321 秒 紧接着的两次查询大概0.791 秒

mysql 查询所有的cate-4 的产品

SELECT * FROM  product p inner join product_category pc inner join category c on p.id=pc.product_id and pc.category_id=c.id where c.code ='cate-4'; -- 毫秒级,时间可以忽略不计, 产品和类目的code都是unique的索引,所以查询速度很快SELECT * FROM  product p inner join product_category pc inner join category c on p.id=pc.product_id and pc.category_id=c.id where c.name ='Category 4'; -- 6.2秒,name不是索引,所以慢。(索引的用处毫无疑问,无需赘述)

场景二:查询多个类目下的产品

查询所有cate-4 加上 cate-5 的产品。(实际上cate-5并不存在,不过不影响测试)

mongod

db.getCollection('products').find({categories:{$in:['cate-4','cate-5']}}) // 0.89 秒; 和查询cate-4的产品相差不多,都是全表扫描

mysql

SELECT * FROM  product p inner join product_category pc inner join category c on p.id = pc.product_id and pc.category_id = c.id where c.code = 'cate-5' or c.code='cate-4'; -- 6.177 秒,SELECT * FROM  product p inner join product_category pc inner join category c on p.id = pc.product_id and pc.category_id = c.id where c.code in('cate-5','cate-4'); -- 6.24 秒

通过上面的测试可以看出,mysql数据库在数据体量大的时候,用or或者in都有很严重的性能问题,可以考虑使用union来代替。一般电商平台的处理方式:如果是后台维护功能应该从业务上来避免这种场景,如果是前端面向用户的功能,需要引入搜索引擎 比如: elasticsearch

场景三:单表无索引

查询名称是iphone的产品

Mysql

select * from product where name='iphone'; -- 0.546 秒,全表扫描

mongo

db.getCollection('products').find({name:'iphone'}) // 0.428 秒

全表扫描两者并无太大的差距。

场景四:单表索引

db.getCollection('products').find({code:'pp-1'})  select * from product where code='pp-1';

一百万条数据,单表索引速度都是毫秒级,时间可以忽略不计。

场景五:单表索引字段使用In来查询

场景二我们提到了Mysql中关联表时使用in查询的效率问题。下面测试下单表的In查询效率, 通过测试我们可以发现单表针对索引的in的查询都是毫秒级的。
mongodb 历时0.004 sec. 索引被用上了

// 非ID的索引字段db.getCollection('products').find({    "code": {        "$in": [            "pp-0",            "pp-1"        ]    }})// _id 主键的$in 查询db.getCollection('products').find({    "_id": {        "$in": [            ObjectId("59cb4952d44efa2eb45d4bf7"),            ObjectId("59cb4952d44efa2eb45d4bf8")        ]    }})

Mysql 也是毫秒级,时间忽略不计

select * from product where code in ('pp-0','pp-4'); // 0.0000 sec
原创粉丝点击