`

数据库写入性能测试小工具

阅读更多

文章来自:http://blog.csdn.net/kongxx/article/details/42360663

 

今天工作需要要写一个小工具来测试一下数据库的写入性能,需要支持多并发,并且支持调整事务提交记录大小,所以就用Java写了一个,就一个类,比较简单但是基本功能都有了,下面看看代码实现

  1. import java.sql.Connection;  
  2. import java.sql.DriverManager;  
  3. import java.sql.PreparedStatement;  
  4. import java.sql.ResultSet;  
  5. import java.sql.ResultSetMetaData;  
  6. import java.sql.SQLException;  
  7. import java.sql.Statement;  
  8. import java.sql.Timestamp;  
  9. import java.sql.Types;  
  10. import java.util.ArrayList;  
  11. import java.util.Calendar;  
  12. import java.util.Collections;  
  13. import java.util.Formatter;  
  14. import java.util.LinkedHashMap;  
  15. import java.util.List;  
  16. import java.util.Map;  
  17. import java.util.Random;  
  18. import java.util.UUID;  
  19. import java.util.concurrent.CountDownLatch;  
  20. import java.util.logging.Level;  
  21. import java.util.logging.Logger;  
  22.    
  23. public class InsertTest {  
  24.    
  25.     private static Logger logger = Logger.getLogger(InsertTest.class.getName());  
  26.    
  27.     private static final String DB_DRIVER = "com.ibm.db2.jcc.DB2Driver";  
  28.     private static final String DB_URL = "jdbc:db2://9.111.251.152:50000/padb";  
  29.     private static final String DB_USERNAME = "db2inst";  
  30.     private static final String DB_PASSWORD = "Letmein";  
  31.    
  32.     private static Random random = new Random(10000);  
  33.    
  34.     private static final String TABLE_NAME = "BENCHMARK";  
  35.    
  36.     private int batchSize;  
  37.    
  38.     private int concurrent;  
  39.    
  40.     private int sampling;  
  41.    
  42.     public static void main(String[] args) throws Exception {  
  43.         printHeader();  
  44.    
  45.         int[] concurrentList = new int[]{151020};  
  46.         int[] batchSizeList = new int[] {10002000500010000};  
  47.         for (int concurrent : concurrentList) {  
  48.             for (int batchSize : batchSizeList) {  
  49.                 new InsertTest(batchSize, concurrent).run(true);  
  50.             }  
  51.             Thread.sleep(10000);  
  52.         }  
  53.     }  
  54.    
  55.     public InsertTest(final int batchSize, final int concurrent) throws Exception {  
  56.         this.batchSize = batchSize;  
  57.         this.concurrent = concurrent;  
  58.         this.sampling = 100;  
  59.     }  
  60.    
  61.     public InsertTest(final int batchSize, final int concurrent, final int sampling) throws Exception {  
  62.         this.batchSize = batchSize;  
  63.         this.concurrent = concurrent;  
  64.         this.sampling = sampling;  
  65.     }  
  66.    
  67.     public void run(boolean printResult) throws Exception {  
  68.         final List<Long> results = Collections.synchronizedList(new ArrayList<Long>());  
  69.         final CountDownLatch startGate = new CountDownLatch(concurrent);  
  70.         final CountDownLatch endGate = new CountDownLatch(concurrent);  
  71.    
  72.         for (int idxConcurrent = 0; idxConcurrent < concurrent; idxConcurrent++) {  
  73.             new Thread(new Runnable() {  
  74.                 public void run() {  
  75.                     startGate.countDown();  
  76.                     try {  
  77.                         long time = execute();  
  78.                         long avg = batchSize * sampling * 1000 / time;;  
  79.                         results.add(Long.valueOf(avg));  
  80.                     } catch(Exception ex) {  
  81.                         ex.printStackTrace();  
  82.                     } finally {  
  83.                         endGate.countDown();  
  84.                     }  
  85.                 }  
  86.             }).start();  
  87.         }  
  88.         endGate.await();  
  89.    
  90.         Collections.sort(results);  
  91.    
  92.         if (printResult) {  
  93.             printResult(batchSize, concurrent, results);  
  94.         }  
  95.     }  
  96.    
  97.     public long execute() throws Exception {  
  98.         Connection conn = getConnection();  
  99.         Map<String, Integer> columns = queryTableColumns(conn);  
  100.         String insertSQL = generateInsertSQL(columns);  
  101.         PreparedStatement ps = conn.prepareStatement(insertSQL);  
  102.         try {  
  103.             long start = System.currentTimeMillis();  
  104.             for (int i = 0; i < sampling; i++) {  
  105.                 execute(conn, ps, columns);  
  106.             }  
  107.             long stop = System.currentTimeMillis();  
  108.             return stop - start;  
  109.         } catch(Exception ex) {  
  110.             logger.log(Level.SEVERE, null, ex);  
  111.             conn.rollback();  
  112.             conn.close();  
  113.             throw ex;  
  114.         } finally {  
  115.             conn.close();  
  116.         }  
  117.     }  
  118.    
  119.     public void execute(Connection conn, PreparedStatement ps, Map<String, Integer> columns) throws Exception {  
  120.         try {  
  121.             for (int idx = 0; idx < batchSize; idx++) {  
  122.                 int idxColumn = 1;  
  123.                 for (String column : columns.keySet()) {  
  124.                     if (column.equalsIgnoreCase("ID")) {  
  125.                         ps.setObject(idxColumn, UUID.randomUUID().toString());  
  126.                     } else {  
  127.                         ps.setObject(idxColumn, generateColumnValue(columns.get(column)));  
  128.                     }  
  129.                     idxColumn ++;  
  130.                 }  
  131.                 ps.addBatch();  
  132.             }  
  133.             ps.executeBatch();  
  134.             conn.commit();  
  135.    
  136.             ps.clearBatch();  
  137.         } catch (SQLException ex) {  
  138.             logger.log(Level.SEVERE, null, ex);  
  139.             if (null != ex.getNextException()) {  
  140.                 logger.log(Level.SEVERE, null, ex.getNextException());  
  141.             }  
  142.             conn.rollback();  
  143.             throw ex;  
  144.         }  
  145.     }  
  146.    
  147.     private String generateInsertSQL(Map<String, Integer> columns) throws SQLException {  
  148.         StringBuilder sb = new StringBuilder();  
  149.         StringBuffer sbColumns = new StringBuffer();  
  150.         StringBuffer sbValues = new StringBuffer();  
  151.    
  152.         sb.append("INSERT INTO ").append(TABLE_NAME);  
  153.    
  154.         for (String column : columns.keySet()) {  
  155.             if (sbColumns.length() > 0) {  
  156.                 sbColumns.append(",");  
  157.                 sbValues.append(",");  
  158.             }  
  159.             sbColumns.append(column);  
  160.             sbValues.append("?");  
  161.         }  
  162.         sb.append("(").append(sbColumns).append(")");  
  163.         sb.append("VALUES");  
  164.         sb.append("(").append(sbValues).append(")");  
  165.         return sb.toString();  
  166.     }  
  167.    
  168.     private Map<String, Integer> queryTableColumns(Connection conn) throws Exception {  
  169.         Map<String, Integer> columns = new LinkedHashMap<String, Integer>();  
  170.         String sql = "SELECT * FROM " + TABLE_NAME + " WHERE 1=0";  
  171.         Statement stmt = conn.createStatement();  
  172.         ResultSet rs = stmt.executeQuery(sql);  
  173.         ResultSetMetaData rsmd = rs.getMetaData();  
  174.         for (int i = 1; i <= rsmd.getColumnCount(); i++) {  
  175.             columns.put(rsmd.getColumnName(i), rsmd.getColumnType(i));  
  176.         }  
  177.         return columns;  
  178.     }  
  179.    
  180.     private Object generateColumnValue(int type) {  
  181.         Object obj = null;  
  182.         switch (type) {  
  183.             case Types.DECIMAL:  
  184.             case Types.NUMERIC:  
  185.             case Types.DOUBLE:  
  186.             case Types.FLOAT:  
  187.             case Types.REAL:  
  188.             case Types.BIGINT:  
  189.             case Types.TINYINT:  
  190.             case Types.SMALLINT:  
  191.             case Types.INTEGER:  
  192.                 obj = random.nextInt(10000);  
  193.                 break;  
  194.             case Types.DATE:  
  195.                 obj = Calendar.getInstance().getTime();  
  196.                 break;  
  197.             case Types.TIMESTAMP:  
  198.                 obj = new Timestamp(System.currentTimeMillis());  
  199.                 break;  
  200.             default:  
  201.                 obj = String.valueOf(random.nextInt(10000));  
  202.                 break;  
  203.         }  
  204.         return obj;  
  205.     }  
  206.    
  207.     private Connection getConnection() throws Exception {  
  208.         Class.forName(DB_DRIVER);  
  209.         Connection conn = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD);  
  210.         conn.setAutoCommit(false);  
  211.         return conn;  
  212.     }  
  213.    
  214.     private static void printHeader() {  
  215.         StringBuilder sb = new StringBuilder();  
  216.         sb.append("\n");  
  217.         sb.append(new Formatter().format("%15s|%15s|%15s|%15s|%15s""BATCH_SIZE""CONCURRENT""AVG (r/s)""MIN (r/s)""MAX (r/s)"));  
  218.         System.out.println(sb.toString());  
  219.     }  
  220.    
  221.     private static void printResult(int batch, int concurrent, List<Long> results) {  
  222.         Long total = Long.valueOf(0);  
  223.         for (Long result : results) {  
  224.             total += result;  
  225.         }  
  226.         StringBuilder sb = new StringBuilder();  
  227.         sb.append(new Formatter().format("%15s|%15s|%15s|%15s|%15s", batch, concurrent, (total/results.size()), results.get(0), results.get(results.size() - 1)));  
  228.         System.out.println(sb.toString());  
  229.     }  
  230. }  

 

要运行测试需要
1. 修改数据库的配置信息
2. 修改TABLE_NAME指定数据库里需要测试的表名,测试程序会查询这个表的定义来生成写入SQL语句
3. 修改concurrentList指定需要测试并发数列表,默认测试1,5,10,20个并发
4. 修改batchSizeList指定每次测试的事务提交记录数据,默认是1000,2000,5000,10000

最后运行测试,会生成类似下面的结果

  1. BATCH_SIZE|     CONCURRENT|      AVG (r/s)|      MIN (r/s)|      MAX (r/s)  
  2.       1000|              1|            ...|            ...|            ...  
  3.       2000|              1|            ...|            ...|            ...  
  4.       5000|              1|            ...|            ...|            ...  
  5.      10000|              1|            ...|            ...|            ...  
  6.       1000|              5|            ...|            ...|            ...  
  7.       2000|              5|            ...|            ...|            ...  
  8.       5000|              5|            ...|            ...|            ...  
  9.      10000|              5|            ...|            ...|            ... 
分享到:
评论

相关推荐

    db数据库写入性能测试

    总结来说,“db数据库写入性能测试”是对数据库在大量数据写入场景下的性能评估,通过工具如YCSB,我们可以深入理解数据库的性能瓶颈,优化配置,确保在高负载环境下仍能保持高效稳定的服务。对于MongoDB和MySQL这样...

    Loadrunner测试数据库性能,测试SQL语句性能的脚本例子.docx

    Loadrunner测试数据库性能、测试SQL语句性能的脚本例子 ...该脚本例子可以用来测试MySQL数据库的性能和SQL语句的性能, Loadrunner是一个功能强大且灵活的性能测试工具,可以用来测试各种类型的系统。

    Benchmark数据库性能测试使用说明书

    Benchmark Factory是Quest公司推出的一个性能测试工具,旨在帮助用户快速、简单地对数据库进行性能测试。该工具提供了向导式的操作界面,让用户可以轻松地创建测试场景、设计测试模型、构建SQL语句,并执行性能测试...

    2009系统架构师大会PPT:邵宗文:数据库极限性能测试修正版

    - 推荐使用MySQLslap作为性能测试工具。 5. **操作系统选择**: - 本案例使用CentOS 5.0 x86_64作为操作系统。 #### 七、测试实施步骤 1. **系统内存限制**: - 通过修改`grub.conf`文件中的`mem=1G`参数,限制...

    洋米&庚顿-联合测试报告-基于边缘计算服务器硬件容错机制-实时数据库功能性能及高可用测试报告.pdf

    具体到数据写入性能测试中,测试案例包括每秒并发写入20万实时数据的测试,以及给定20万点急速写入1200万条实时数据的测试,测试了不同线程下的数据入库响应耗时、数据库服务器压力、CPU和内存的占用率以及磁盘写入...

    使用JAVA内存数据库h2database性能优化

    8. **监控与调优**:持续监控数据库性能,使用分析工具如JMX或h2database的内置监控功能,找出性能瓶颈并进行针对性优化。 通过这些策略,h2database能够在内存中快速处理大量数据,从而解决IO瓶颈问题,提高系统...

    很好很方便的数据库测试工具

    这款测试工具能够帮助用户验证与这些数据库系统的连接,确保数据的正常读取、写入和管理。 在标签中,“数据库”涵盖了数据存储、管理和查询的整个领域,它涉及到表的设计、索引的创建、事务处理、安全性设置等多个...

    .Net数据库生成测试数据工具类

    在.NET开发环境中,数据库测试数据的生成是必不可少的环节,特别是在进行性能测试、压力测试或者功能验证时。本文将详细讲解如何使用一个自定义的.NET工具类来高效地生成数据库测试数据,支持包括MSSQL、Oracle、...

    MySQL数据库性能优化研究.docx

    3. Sysbench:一款开源的性能测试工具,可以模拟多用户并发访问数据库的过程,测试 MySQL 服务器的 OLTP 性能、CPU 性能和磁盘 I/O 性能等指标。 七、结论 MySQL 数据库性能优化是一个持续不断的过程。通过调整...

    OPS性能测试工具(多线程)

    OPS性能测试工具是一种专门用于评估系统在执行OPS(Operations Per Second)操作时的性能的软件。在多线程环境下,这种工具能够同时进行大量的读写文件操作,从而更准确地模拟真实工作负载并分析系统的并发处理能力...

    mysql数据库转换成SQLserver工具包

    MySQL到SQL Server转换工具包是针对数据库管理员和开发人员的一款实用工具,它的主要功能是将MySQL数据库结构和数据无缝地迁移到SQL Server环境中。这样的转换对于那些需要在不同数据库系统间进行迁移或整合项目的...

    log4net写入数据库

    除了基本的数据库写入,log4net还支持自定义数据库适配器,允许你扩展其功能,以适应特定的数据库系统或特殊需求。此外,考虑到性能和可扩展性,还可以使用缓冲策略,如BulkInsert,来批量处理日志记录,减少对...

    易语言实施小工具(带数据库)

    本工具使用ADO方式来操作数据库,意味着它可以连接到多种类型的数据库,如MS SQL Server、Access等,通过ADO提供的接口执行SQL语句,进行数据的读取、写入、更新和删除等操作。ADO的优势在于其简单易用,且性能高效...

    行业-06 生产经验:互联网公司的生产环境数据库是如何进行性能测试的.rar

    在互联网公司中,数据库性能测试是确保系统稳定、高效运行的关键环节。生产环境数据库的性能测试涉及多个层面,包括但不限于数据库设计、查询优化、硬件配置、并发处理能力以及故障恢复策略。下面将详细阐述这些重要...

    SQL性能测试工具sqlstress安装文件及实验手册

    总的来说,Sqlstress作为一款免费的SQL性能测试工具,其易用性和实用性使其在数据库性能测试领域占有重要地位。通过熟练掌握Sqlstress的使用,数据库管理员能够更好地管理和优化SQL Server,确保系统的高效稳定运行...

    delphi编写的数据库连接测试

    - **性能测试**:在大规模数据或高并发场景下测试数据库连接,检查性能是否满足需求,例如查询速度、内存占用等。 - **断开和重新连接**:测试断开和重新连接数据库的功能,确保程序在连接丢失后能恢复连接。 通过...

    java服务程序性能测试总结

    JMeter是广泛使用的性能测试工具,适用于接口和Web应用的压测。以下是使用JMeter时的一些关键点: 1. **编写接口测试代码**:编写接口测试代码是为了验证接口功能的正确性,便于在JMeter中构建压测脚本。 2. **调用...

    分布式关系型数据库恢复点目标测试方法.pdf

    在实际工程实践中,为了测试和评价分布式关系型数据库的RPO,可以搭建测试环境,并利用测试工具如LoadRunner来获取相关性能指标。具体方法包括记录平均响应时间、每秒虚拟用户HTTP请求数、Tomcat日志等,通过对这些...

    MYSQL官方最新测试数据库 test_db.zip

    使用这样的测试数据库,用户可以在不干扰生产环境的情况下,安全地试验新功能、调试代码或进行性能基准测试。 "test_db"很可能是数据库的名称,而其他出现在标签中的"mysqltest_db", "mysql_test_db", "mysql-test-...

Global site tag (gtag.js) - Google Analytics