• Java使用JDBC连接数据库逐条插入数据、批量插入数据、以及通过SQL语句批量导入数据的效率对比


    测试用的示例java代码:

    package com.zifeiy.test.normal;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.apache.commons.exec.ExecuteException;
    
    
    public class Test20181120 {
    	
    	public static void main(String[] args) throws ExecuteException, IOException, ClassNotFoundException, SQLException {
    		
    		// 生成1万条测试数据
    		List<TestObject> testObjectList = new ArrayList<TestObject>();
    		for (int i = 0; i < 10000; i ++) {
    			testObjectList.add(new TestObject());
    		}
    		
    		// 生成CSV文件
    		File csvFile = new File("D:\test.csv");
    		FileOutputStream fos = new FileOutputStream(csvFile);
            OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
            String content = "";
            for (TestObject e : testObjectList) {
            	content += e.toCsvLine();
            }
            osw.write(content);
            osw.flush();
    		
            // MySQL依次执行1万条Insert的SQL
    	    Class.forName("com.mysql.jdbc.Driver");
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useSSL=false", "root", "password");
            Statement statement = connection.createStatement();
            
            // drop table的SQL
            String dropTableSQL = "drop table if exists test_table";
            // create table的SQL
            String createTableSQL = "create table test_table ( id integer, name varchar(20), age integer, brief varchar(100) )";
            
            long beginTime, endTime;
            // 使用JDBC一次插入
            statement.execute(dropTableSQL);
            statement.execute(createTableSQL);
            beginTime = System.currentTimeMillis();
            for (TestObject e : testObjectList) {
            	statement.execute(e.toInsertSQL());
            }
            endTime = System.currentTimeMillis();
            System.out.println("timer 1 : " + (endTime - beginTime) + " ms");
            
            // 使用JDBC批量插入
            statement.execute(dropTableSQL);
            statement.execute(createTableSQL);
            beginTime = System.currentTimeMillis();
            for (TestObject e : testObjectList) {
            	statement.addBatch(e.toInsertSQL());
            }
            statement.executeBatch();
            endTime = System.currentTimeMillis();
            System.out.println("timer 2 : " + (endTime - beginTime) + " ms");
            
            // 使用SQL批量导入CSV文件内容
            statement.execute(dropTableSQL);
            statement.execute(createTableSQL);
            beginTime = System.currentTimeMillis();
            statement.execute(
    "load data local infile 'd:\\test.csv' 
    " + 
    "into table testdb.test_table character set utf8
    " + 
    "fields terminated by ',' optionally enclosed by '"' escaped by '"' 
    " + 
    "lines terminated by '\r\n'"        		
    );
            statement.executeBatch();
            endTime = System.currentTimeMillis();
            System.out.println("timer 3 : " + (endTime - beginTime) + " ms");
    	}
    	
    	static class TestObject {
    		private Integer id;
    		private String name;
    		private Integer age;
    		private String brief;
    		public TestObject() {
    			this.id = (int) ( Math.random() * 1e9);
    			this.name = (id % 4 == 0) ? "刘德华" : ( (id % 4 == 1) ? "周杰伦" : ( (id % 4 == 2) ? "麦哲伦" : "范晓萱" ) );
    			this.age = (int) (Math.random() * 100 );
    			this.brief = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    		}
    		public String toInsertSQL() {
    			return String.format("insert into test_table (id, name, age, brief) values (%d, '%s', %d, '%s')", id, name, age, brief);
    		}
    		public String toCsvLine() {
    			return String.format("%d,"%s",%d,"%s"
    ", id, name, age, brief);
    		}
    	}
    	
    }
    
    

    其中,我们首先创造了1万条随机数据,然后生成这1万条数据对应的CSV文件,
    然后我们通过以下三种方式进行对这1万条数据:

    • 使用JDBC逐条插入;
    • 使用JDBC批量插入;
    • 使用load dataSQL语句导入CSV文件。

    执行的结果如下:

    结果1

    timer 1 : 31417 ms
    timer 2 : 27559 ms
    timer 3 : 239 ms
    

    结果2

    timer 1 : 31428 ms
    timer 2 : 28009 ms
    timer 3 : 223 ms
    

    结果3

    timer 1 : 30779 ms
    timer 2 : 30969 ms
    timer 3 : 441 ms
    

    可以发现,使用SQL批量导入文本文件的方法明显比JDBC插入快不止一个数量级。

  • 相关阅读:
    org.hibernate.HibernateException: Could not obtain transactionsynchronized Session for current thread
    ajax上传文件
    iphone 图层操作
    什么是OAuth授权
    UIWebView得到加载页的title
    转iphone 动画实现方法
    c#字符串转datatime时,因操作系统不一致产生的问题解决方法
    Bold font in IPhone UILabel
    五种开源协议的比较(BSD,Apache,GPL,LGPL,MIT)
    包含iphone4在内的icon,default及图片处理方法
  • 原文地址:https://www.cnblogs.com/zifeiy/p/9990119.html
Copyright © 2020-2023  润新知