Mongodb Mysql 小测试 (To Be Continued)
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 數據如下:
| ‘1’ | ‘cate-1’ | ‘Category 1’ |
| ‘2’ | ‘cate-2’ | ‘Category 2’ |
| ‘3’ | ‘cate-3’ | ‘Category 3’ |
| ‘4’ | ‘cate-4’ | ‘Category 4’ |
Product 數據如下
| ‘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. 索引被用上了
Mysql 也是毫秒級,時間忽略不計
select * from product where code in ('pp-0','pp-4'); // 0.0000 sec總結
以上是生活随笔為你收集整理的Mongodb Mysql 小测试 (To Be Continued)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言中使用的字符常量其起止标记符是,2
- 下一篇: SAS2x28扩展卡