对mysql数据库批量插入数据的速度测试 (含代码可以参考) (转)

对mysql数据库批量插入数据的速度测试

分类: 数据库 3304人阅读 评论(1) 收藏 举报

    今天,对mysql数据库的插入数据的速度做了个简单的测试。
   JdbcUtil.java

 

[java] view plaincopy
 
  1. package utils;  
  2. import java.sql.*;  
  3. public class JdbcUtil {  
  4.   
  5.     private final static String DB_DRIVER = "com.mysql.jdbc.Driver";  
  6.     private final static String DB_CONNECTION = "jdbc:mysql://localhost:3306/";  
  7.     private final static String DB_NAME = "root";  
  8.     private final static String DB_PWd = "root";  
  9.       
  10.     static {  
  11.         try {  
  12.             Class.forName(DB_DRIVER);  
  13.         } catch (ClassNotFoundException e) {  
  14.             e.printStackTrace();  
  15.         }  
  16.     }  
  17.   
  18.     public static Connection getConnection() {  
  19.         Connection conn = null;  
  20.         try {  
  21.             conn = DriverManager  
  22.                     .getConnection(DB_CONNECTION,  
  23.                             DB_NAME, DB_PWd);  
  24.         } catch (SQLException e) {  
  25.             e.printStackTrace();  
  26.         }  
  27.         return conn;  
  28.     }  
  29.   
  30.     public static Statement getStatement(Connection conn) {  
  31.         Statement stmt = null;  
  32.         try {  
  33.             stmt = conn.createStatement();  
  34.         } catch (SQLException e) {  
  35.             e.printStackTrace();  
  36.         }  
  37.         return stmt;  
  38.     }  
  39.   
  40.     public static PreparedStatement getPreparedStatement(Connection conn, String sql) {  
  41.         PreparedStatement pstmt = null;  
  42.         try {  
  43.             pstmt = conn.prepareStatement(sql);  
  44.         } catch (SQLException e) {  
  45.             e.printStackTrace();  
  46.         }  
  47.         return pstmt;  
  48.     }  
  49.   
  50.     public static ResultSet getRs(Statement stmt, String sql) {  
  51.         ResultSet rs = null;  
  52.         try {  
  53.             rs = stmt.executeQuery(sql);  
  54.         } catch (SQLException e) {  
  55.             e.printStackTrace();  
  56.         }  
  57.         return rs;  
  58.     }  
  59.   
  60.   
  61.     public static void close(Statement stmt) {  
  62.         if (stmt != null) {  
  63.             try {  
  64.                 stmt.close();  
  65.             } catch (SQLException e) {  
  66.                 e.printStackTrace();  
  67.             }  
  68.         }  
  69.     }  
  70.   
  71.     public static void close(ResultSet rs) {  
  72.         if (rs != null) {  
  73.             try {  
  74.                 rs.close();  
  75.             } catch (SQLException e) {  
  76.                 e.printStackTrace();  
  77.             }  
  78.         }  
  79.     }  
  80.   
  81.     public static void close(Connection conn) {  
  82.         if (conn != null) {  
  83.             try {  
  84.                 conn.close();  
  85.             } catch (SQLException e) {  
  86.                 e.printStackTrace();  
  87.             }  
  88.         }  
  89.     }  
  90.   
  91. }  

 


   SqlTest.java

 

[java] view plaincopy
 
  1. package test;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.PreparedStatement;  
  5. import java.sql.SQLException;  
  6. import java.sql.Statement;  
  7.   
  8. import utils.JdbcUtil;  
  9.   
  10. public class SqlTest {  
  11.   
  12.     private  final String DBNAME = "test";  
  13.     private  final String TABLENAME = "mytest";  
  14.       
  15.     public void createTable(){  
  16.           
  17.         //String sql_select_db = "use "+ DBNAME;  
  18.         String sql_drop = "drop table if exists " + DBNAME + "." + TABLENAME;  
  19.         String sql_create = "create table "+ DBNAME + "." + TABLENAME+"(id varchar(10) primary key,name varchar(10))";  
  20.           
  21.         Connection conn = JdbcUtil.getConnection();  
  22.         Statement stmt = JdbcUtil.getStatement(conn);  
  23.           
  24.         try {  
  25.             //System.out.println(stmt.execute(sql_select_db));  
  26.             stmt.execute(sql_drop);  
  27.             stmt.execute(sql_create);  
  28.         } catch (SQLException e) {  
  29.             e.printStackTrace();  
  30.         }finally{  
  31.             JdbcUtil.close(conn);  
  32.             JdbcUtil.close(stmt);  
  33.         }  
  34.     }  
  35.       
  36.     public void add(){  
  37.           
  38.         String sql_add = "insert into " + DBNAME + "."+ TABLENAME + " values(?,?)";  
  39.               
  40.         Connection conn = JdbcUtil.getConnection();  
  41.         PreparedStatement pstmt = JdbcUtil.getPreparedStatement(conn, sql_add);  
  42.           
  43.         try {  
  44.             pstmt.setString(1"1006");  
  45.             pstmt.setString(2"q1006");  
  46.             pstmt.executeUpdate();  
  47.         } catch (SQLException e) {  
  48.             e.printStackTrace();  
  49.         }finally{  
  50.             JdbcUtil.close(conn);  
  51.             JdbcUtil.close(pstmt);  
  52.         }  
  53.     }  
  54.       
  55.     public void addBatchTest(){  
  56.           
  57.         String sql_add = "insert into "+ DBNAME + "." +TABLENAME + " values(?,?)";  
  58.           
  59.         Connection conn = JdbcUtil.getConnection();  
  60.         PreparedStatement pstmt = JdbcUtil.getPreparedStatement(conn, sql_add);  
  61.           
  62.         long startTime = System.currentTimeMillis();  
  63.           
  64.         try {  
  65.             int count = 0;  
  66.             for(int i = 0; i < 100000; i++){  
  67.                 pstmt.setString(1, i+"");  
  68.                 pstmt.setString(2"q"+ i);  
  69.                 conn.setAutoCommit(false);   //若改为true 插入中遇到主键冲突还会继续插入,具体看需求    ——???是这样吗?
  70.                 pstmt.addBatch();  
  71.                 count ++;  
  72.                 if(count >= 10000){  
  73.                     count = 0;  
  74.                     pstmt.executeBatch();  
  75.                     conn.commit();  
  76.                 }  
  77.             }  
  78.             pstmt.executeBatch();  
  79.             conn.commit();  
  80.         System.out.println( (System.currentTimeMillis() - startTime) + "ms");  
  81.               
  82.         } catch (SQLException e) {  
  83.             e.printStackTrace();  
  84.         }finally{  
  85.             JdbcUtil.close(conn);  
  86.             JdbcUtil.close(pstmt);  
  87.         }  
  88.   
  89.           
  90.     }  
  91.     /** 
  92.      * @param args 
  93.      */  
  94.     public static void main(String[] args) {  
  95.         SqlTest sqlTest = new SqlTest();  
  96.         sqlTest.createTable();  
  97.         //sqlTest.add();  
  98.         sqlTest.addBatchTest();  
  99.     }  
  100.   
  101. }  

 

  

背景:
   1、mysql数据库
   2、表结构为
      id varchar(10)
      name varchar(10)
   3、采用非自动提交的PrepareStatement批处理

   测试结果: 
   数据量(条)   插入所需时间(ms)
     1                 0
     10                15
     100               62
     1,000             422
     10,000            2,922
     100,000           26,922
     1000,000          272,219

  

测试过程学习到的:
     1、批处理要conn.setAutoCommit(false)(默认会自动提交,不能达到批处理的目的,速度极慢!)。
     2、pstmt.executeBatch();
          conn.commit();
        要提交,数据库才会有数据。
     3、避免内存溢出,应每x(如:万)条提交一次数据。
     4、可用“数据库名.表名”的方法来访问数据库表
        这样,则在写JdbcUtil的DB_CONNECTION = "jdbc:mysql://localhost:3306/"时,
        可不具体到数据库,方便跨数据库的数据操作。
     5、Statement和PrepareStatement不仅可以操作DDL,添加删除表和数据库的sql都可以操作,用execute(String sql)方法。

posted @ 2013-10-17 22:27  晴心  阅读(635)  评论(0编辑  收藏  举报