分享

【测试】MySQL和MongoDB的性能测试

 CevenCheng 2011-05-06

软硬件环境

MySQL版本:5.1.50,驱动版本:5.1.6(最新的5.1.13有很多杂七杂八的问题)

MongoDB版本:1.6.2,驱动版本:2.1

操作系统:Windows XP SP3(这个影响应该不大)

CPUIntel Core2 E6550 2.33G

内存:2G(足够了)

 

MySQL启动参数:bin\mysqld --no-defaults --console --character-set-server=utf8 --max_connections=1000 --max_user_connections=1000

MongoDB启动参数:bin\mongod --dbpath data\ --directoryperdb --rest --maxConns 1000 –quiet

除了加大最大连接数之外,均使用默认参数


测试

该测试主要为改进当前系统的日志的存储和查询性能提供参考,所以表的创建也以实际情况为例,下面是MySQL的建表语句:

 

CREATE TABLE `flt_evecurrent` (

  `NodeID` int(11) NOT NULL DEFAULT '0',

  `FltID` int(11) NOT NULL DEFAULT '0',

  `ObjID` int(11) DEFAULT NULL,

  `StationID` int(11) DEFAULT NULL,

  `EveType` int(11) DEFAULT NULL,

  `Severity` int(11) DEFAULT NULL,

  `ReportTime` date DEFAULT NULL,

  `CreateTime` date DEFAULT NULL,

  `EveContent` varchar(1024) DEFAULT NULL,

  `EveDesc` varchar(256) DEFAULT NULL,

  PRIMARY KEY (`NodeID`,`FltID`)

);

 

MongoDB类似,索引按照查询语句的查询字段创建,该例子中为ObjIDCreateTime两个字段创建索引。

 

分别插入100万条记录,并对其做100个用户并发查询操作。

MySQL每一次都Drop表,MongoDB每一次都删除data目录。

查询的时候,从第二次查询开始,连续记录三次。


结果

 

 

插入时间

查询时间

MySQL InnoDB引擎无索引

1033

39.516秒、35.907秒、39.907

MySQL InnoDB引擎有索引

1116

非常不稳定:22.531秒、13.078秒、23.078秒、26.047秒、21.234秒、28.469秒、20.922秒、13.328

MySQL MyISAM引擎无索引

321

22.812秒、23.343秒、23.125

MySQL MyISAM引擎有索引

350

10.312秒、10.359秒、10.296

MongoDB 无索引

37

59.531秒、60.063秒、59.891

MongoDB 有索引

50

3.484秒、3.453秒、3.453

 

 

磁盘空间占用(有索引时候的占用,无索引情况差不多):

MySQL MyISAM57MB

MySQL InnoDB264MB

MongoDB464MB

 

另外测试中还发现一个有意思的现象,如果MongoDB查询中,如果单独查询ObjID字段,耗时约1秒,如果单独查询CreateTime字段,耗时约10秒,如果两个字段合起来查,就是上面的结果,约3秒,估计MongoDB内部对查询顺序作了优化吧。

 

更多关于MySQL的详细信息,或者下载地址请点这里

相关话题

该测试没有对MySQL和MongoDB的启动参数作任何优化,因为根据经验即便优化性能也不会有数量级的提升,另外也只是给一个大概的印象吧,第一印象总是很重要的,呵呵。

下面是代码:

MySQL插入

  1. import java.sql.Connection;  
  2. import java.sql.DriverManager;  
  3. import java.sql.Statement;  
  4. import java.util.Random;  
  5.   
  6. public class AddData {  
  7.   
  8.     public static void main(String[] args) throws Exception {  
  9.         Connection connection;  
  10.         Statement statement;  
  11.   
  12.         Class.forName("com.mysql.jdbc.Driver");  
  13.         connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test""root""");  
  14.         statement = connection.createStatement();  
  15.   
  16.         // 清理表  
  17.         statement.executeUpdate("truncate table flt_evecurrent");  
  18.   
  19.         // 增加记录  
  20.         Random random = new Random(System.currentTimeMillis());  
  21.         for (int fltId = 0; fltId < 1000000; fltId++) {  
  22.             if ((fltId % 10000) == 0) {  
  23.                 System.out.println(fltId);  
  24.             }  
  25.             int nodeId = 0;  
  26.             int objId = random.nextInt(100);  
  27.             int stationId = objId;  
  28.             int eveType = 0;  
  29.             int severity = 0;  
  30.             String reportTime = String.format("2010-09-%d", fltId / 100000 + 1);  
  31.             String createTime = reportTime;  
  32.             String eveContent = "ContentContentContent";  
  33.             String eveDesc = "DescDescDesc";  
  34.             String sql = String.format("insert into flt_evecurrent (NodeID, FltID, ObjID, StationID, EveType, Severity, ReportTime, CreateTime, EveContent, EveDesc) "  
  35.                     + "values (%d, %d, %d, %d, %d, %d, '%s', '%s', '%s', '%s')",  
  36.                     nodeId, fltId, objId, stationId, eveType, severity, reportTime, createTime, eveContent, eveDesc);  
  37.             statement.executeUpdate(sql);  
  38.         }  
  39.   
  40.         statement.close();  
  41.         connection.close();  
  42.     }  
  43. }  

MySQL查询

  1. import java.sql.Connection;  
  2. import java.sql.DriverManager;  
  3. import java.sql.ResultSet;  
  4. import java.sql.SQLException;  
  5. import java.sql.Statement;  
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8. import java.util.logging.Level;  
  9. import java.util.logging.Logger;  
  10. import org.junit.AfterClass;  
  11. import org.junit.BeforeClass;  
  12. import org.junit.Test;  
  13.   
  14. public class PerfTest {  
  15.   
  16.     public PerfTest() {  
  17.     }  
  18.   
  19.     @BeforeClass  
  20.     public static void setUpClass() throws Exception {  
  21.     }  
  22.   
  23.     @AfterClass  
  24.     public static void tearDownClass() throws Exception {  
  25.     }  
  26.   
  27.     @Test  
  28.     public void test() throws Exception {  
  29.         Class.forName("com.mysql.jdbc.Driver");  
  30. //        final Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");  
  31.   
  32.         List<Thread> threads = new ArrayList<Thread>();  
  33.         for (int i = 0; i < 100; i++) {  
  34.             Thread thread = new Thread(new Runnable() {  
  35.   
  36.                 public void run() {  
  37.                     Connection connection = null;  
  38.                     Statement statement = null;  
  39.                     ResultSet resultSet = null;  
  40.                     try {  
  41.                         connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test""root""");  
  42.                         statement = connection.createStatement();  
  43.                         System.out.println(String.format("线程%d查询开始", Thread.currentThread().getId()));  
  44.                         resultSet = statement.executeQuery("select count(*) from flt_evecurrent where objid in (30,50,70) and createtime between '2010-09-03' and '2010-09-07'");  
  45.                         resultSet.first();  
  46.                         System.out.println(String.format("数量:%d", resultSet.getLong("count(*)")));  
  47.                         System.out.println(String.format("线程%d查询结束", Thread.currentThread().getId()));  
  48.                     } catch (Exception ex) {  
  49.                         Logger.getLogger(PerfTest.class.getName()).log(Level.SEVERE, null, ex);  
  50.                     } finally {  
  51.                         try {  
  52.                             connection.close();  
  53.                         } catch (SQLException ex) {  
  54.                             Logger.getLogger(PerfTest.class.getName()).log(Level.SEVERE, null, ex);  
  55.                         }  
  56.                     }  
  57.                 }  
  58.             });  
  59.             thread.start();  
  60.             threads.add(thread);  
  61.         }  
  62.   
  63.         for (Thread thread : threads) {  
  64.             thread.join();  
  65.         }  
  66.   
  67. //        connection.close();  
  68.     }  
  69. }  
MongoDB插入

  1. import com.mongodb.BasicDBObject;  
  2. import com.mongodb.DB;  
  3. import com.mongodb.DBCollection;  
  4. import com.mongodb.Mongo;  
  5. import java.util.Calendar;  
  6. import java.util.Date;  
  7. import java.util.Random;  
  8.   
  9. public class AddData {  
  10.   
  11.     public static void main(String[] args) throws Exception {  
  12.         Mongo mongo = new Mongo("localhost"27017);  
  13.         DB db = mongo.getDB("test");  
  14.         DBCollection coll = db.getCollection("flt_evecurrent");  
  15.   
  16.         // 删除表  
  17.         coll.drop();  
  18.   
  19.         // 增加索引  
  20.         coll.createIndex(new BasicDBObject("ObjID"1));  
  21.         coll.createIndex(new BasicDBObject("CreateTime"1));  
  22.   
  23.         // 增加记录  
  24.         Random random = new Random(System.currentTimeMillis());  
  25.         Calendar calendar = Calendar.getInstance();  
  26.         for (int fltId = 0; fltId < 1000000; fltId++) {  
  27.             if ((fltId % 10000) == 0) {  
  28.                 System.out.println(fltId);  
  29.             }  
  30.             int nodeId = 0;  
  31.             int objId = random.nextInt(100);  
  32.             int stationId = objId;  
  33.             int eveType = 0;  
  34.             int severity = 0;  
  35.             calendar.set(20109, fltId / 100000 + 1);  
  36.             Date reportTime = calendar.getTime();  
  37.             Date createTime = reportTime;  
  38.             String eveContent = "ContentContentContent";  
  39.             String eveDesc = "DescDescDesc";  
  40.             BasicDBObject obj = new BasicDBObject();  
  41.             obj.put("NodeID", nodeId);  
  42.             obj.put("FltID", fltId);  
  43.             obj.put("ObjID", objId);  
  44.             obj.put("StationID", stationId);  
  45.             obj.put("EveType", eveType);  
  46.             obj.put("Severity", severity);  
  47.             obj.put("ReportTime", reportTime);  
  48.             obj.put("CreateTime", createTime);  
  49.             obj.put("EveContent", eveContent);  
  50.             obj.put("EveDesc", eveDesc);  
  51.             coll.insert(obj);  
  52.         }  
  53.     }  
  54. }  

MongoDB查询

  1. import com.mongodb.BasicDBObject;  
  2. import com.mongodb.DB;  
  3. import com.mongodb.DBCollection;  
  4. import com.mongodb.Mongo;  
  5. import java.util.ArrayList;  
  6. import java.util.Calendar;  
  7. import java.util.Date;  
  8. import java.util.List;  
  9. import org.junit.AfterClass;  
  10. import org.junit.BeforeClass;  
  11. import org.junit.Test;  
  12.   
  13. public class PerfTest {  
  14.   
  15.     public PerfTest() {  
  16.     }  
  17.   
  18.     @BeforeClass  
  19.     public static void setUpClass() throws Exception {  
  20.     }  
  21.   
  22.     @AfterClass  
  23.     public static void tearDownClass() throws Exception {  
  24.     }  
  25.   
  26.     @Test  
  27.     public void test() throws Exception {  
  28.         // 增大Mongo驱动的并发连接数量  
  29.         System.setProperty("MONGO.POOLSIZE""1000");  
  30.   
  31.         Mongo mongo = new Mongo("localhost"27017);  
  32.         DB db = mongo.getDB("test");  
  33.         final DBCollection coll = db.getCollection("flt_evecurrent");  
  34.   
  35.         Calendar calendar = Calendar.getInstance();  
  36.         calendar.set(201093);  
  37.         Date beginTime = calendar.getTime();  
  38.         calendar.set(201097);  
  39.         Date endTime = calendar.getTime();  
  40.         List objIds = new ArrayList();  
  41.         objIds.add(30);  
  42.         objIds.add(50);  
  43.         objIds.add(70);  
  44.         final BasicDBObject query = new BasicDBObject();  
  45.         query.put("CreateTime"new BasicDBObject("$gte", beginTime).append("$lte", endTime));  
  46.         query.put("ObjID"new BasicDBObject("$in", objIds));  
  47.   
  48.         List<Thread> threads = new ArrayList<Thread>();  
  49.         for (int i = 0; i < 100; i++) {  
  50.             Thread thread = new Thread(new Runnable() {  
  51.   
  52.                 public void run() {  
  53.                     System.out.println(String.format("线程%d查询开始", Thread.currentThread().getId()));  
  54.                     long count = coll.getCount(query);  
  55.                     System.out.println(String.format("数量:%d", count));  
  56.                     System.out.println(String.format("线程%d查询结束", Thread.currentThread().getId()));  
  57.                 }  
  58.             });  
  59.             thread.start();  
  60.             threads.add(thread);  
  61.         }  
  62.   
  63.         for (Thread thread : threads) {  
  64.             thread.join();  
  65.         }  
  66.     }  
  67. }  

MySQL的建表语句

  1. -- MyISAM无索引  
  2. DROP TABLE `flt_evecurrent`;  
  3. CREATE TABLE `flt_evecurrent` (  
  4.   `NodeID` int(11) NOT NULL DEFAULT '0',  
  5.   `FltID` int(11) NOT NULL DEFAULT '0',  
  6.   `ObjID` int(11) DEFAULT NULL,  
  7.   `StationID` int(11) DEFAULT NULL,  
  8.   `EveType` int(11) DEFAULT NULL,  
  9.   `Severity` int(11) DEFAULT NULL,  
  10.   `ReportTime` date DEFAULT NULL,  
  11.   `CreateTime` date DEFAULT NULL,  
  12.   `EveContent` varchar(1024) DEFAULT NULL,  
  13.   `EveDesc` varchar(256) DEFAULT NULL,  
  14.   PRIMARY KEY (`NodeID`,`FltID`)  
  15. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;  
  16.   
  17. -- MyISAM有索引  
  18. DROP TABLE `flt_evecurrent`;  
  19. CREATE TABLE `flt_evecurrent` (  
  20.   `NodeID` int(11) NOT NULL DEFAULT '0',  
  21.   `FltID` int(11) NOT NULL DEFAULT '0',  
  22.   `ObjID` int(11) DEFAULT NULL,  
  23.   `StationID` int(11) DEFAULT NULL,  
  24.   `EveType` int(11) DEFAULT NULL,  
  25.   `Severity` int(11) DEFAULT NULL,  
  26.   `ReportTime` date DEFAULT NULL,  
  27.   `CreateTime` date DEFAULT NULL,  
  28.   `EveContent` varchar(1024) DEFAULT NULL,  
  29.   `EveDesc` varchar(256) DEFAULT NULL,  
  30.   PRIMARY KEY (`NodeID`,`FltID`),  
  31.   KEY `ObjID` (`ObjID`),  
  32.   KEY `CreateTime` (`CreateTime`)  
  33. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;  
  34.   
  35. -- InnoDB无索引  
  36. DROP TABLE `flt_evecurrent`;  
  37. CREATE TABLE `flt_evecurrent` (  
  38.   `NodeID` int(11) NOT NULL DEFAULT '0',  
  39.   `FltID` int(11) NOT NULL DEFAULT '0',  
  40.   `ObjID` int(11) DEFAULT NULL,  
  41.   `StationID` int(11) DEFAULT NULL,  
  42.   `EveType` int(11) DEFAULT NULL,  
  43.   `Severity` int(11) DEFAULT NULL,  
  44.   `ReportTime` date DEFAULT NULL,  
  45.   `CreateTime` date DEFAULT NULL,  
  46.   `EveContent` varchar(1024) DEFAULT NULL,  
  47.   `EveDesc` varchar(256) DEFAULT NULL,  
  48.   PRIMARY KEY (`NodeID`,`FltID`)  
  49. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  
  50.   
  51. -- InnoDB有索引  
  52. DROP TABLE `flt_evecurrent`;  
  53. CREATE TABLE `flt_evecurrent` (  
  54.   `NodeID` int(11) NOT NULL DEFAULT '0',  
  55.   `FltID` int(11) NOT NULL DEFAULT '0',  
  56.   `ObjID` int(11) DEFAULT NULL,  
  57.   `StationID` int(11) DEFAULT NULL,  
  58.   `EveType` int(11) DEFAULT NULL,  
  59.   `Severity` int(11) DEFAULT NULL,  
  60.   `ReportTime` date DEFAULT NULL,  
  61.   `CreateTime` date DEFAULT NULL,  
  62.   `EveContent` varchar(1024) DEFAULT NULL,  
  63.   `EveDesc` varchar(256) DEFAULT NULL,  
  64.   PRIMARY KEY (`NodeID`,`FltID`),  
  65.   KEY `ObjID` (`ObjID`),  
  66.   KEY `CreateTime` (`CreateTime`)  
  67. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多