JAVA JDBC大数据量导入Mysql

时间:2023-03-10 02:59:04
JAVA JDBC大数据量导入Mysql

转自https://blog.****.net/q6834850/article/details/73726707?tdsourcetag=s_pctim_aiomsg


采用JDBC批处理(开启事务、无事务)

采用JDBC批处理时需要注意一下几点:

1、在URL连接时需要开启批处理、以及预编译 
String url = “jdbc:mysql://localhost:3306/User?rewriteBatched 
-Statements=true&useServerPrepStmts=false”;

2、PreparedStatement预处理sql语句必须放在循环体外


代码如下:

    private long begin = 33112001;//起始id
private long end = begin+100000;//每次循环插入的数据量
private String url = "jdbc:mysql://localhost:3306/bigdata?useServerPrepStmts=false&rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8";
private String user = "root";
private String password = "0203"; @org.junit.Test
public void insertBigData() {
//定义连接、statement对象
Connection conn = null;
PreparedStatement pstm = null;
try {
//加载jdbc驱动
Class.forName("com.mysql.jdbc.Driver");
//连接mysql
conn = DriverManager.getConnection(url, user, password);
//将自动提交关闭
// conn.setAutoCommit(false);
//编写sql
String sql = "INSERT INTO person VALUES (?,?,?,?,?,?,?)";
//预编译sql
pstm = conn.prepareStatement(sql);
//开始总计时
long bTime1 = System.currentTimeMillis(); //循环10次,每次十万数据,一共1000万
for(int i=0;i<10;i++) { //开启分段计时,计1W数据耗时
long bTime = System.currentTimeMillis();
//开始循环
while (begin < end) {
//赋值
pstm.setLong(1, begin);
pstm.setString(2, RandomValue.getChineseName());
pstm.setString(3, RandomValue.name_sex);
pstm.setInt(4, RandomValue.getNum(1, 100));
pstm.setString(5, RandomValue.getEmail(4, 15));
pstm.setString(6, RandomValue.getTel());
pstm.setString(7, RandomValue.getRoad());
//添加到同一个批处理中
pstm.addBatch();
begin++;
}
//执行批处理
pstm.executeBatch();
// //提交事务
// conn.commit();
//边界值自增10W
end += 100000;
//关闭分段计时
long eTime = System.currentTimeMillis();
//输出
System.out.println("成功插入10W条数据耗时:"+(eTime-bTime));
}
//关闭总计时
long eTime1 = System.currentTimeMillis();
//输出
System.out.println("插入100W数据共耗时:"+(eTime1-bTime1));
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
}

接着测试
      开启事务,每次循环插入10W条数据,循环10次,一共100W条数据。结果如下图: 
JAVA JDBC大数据量导入Mysql

成功插入10W条数据耗时:3482 
成功插入10W条数据耗时:1776 
成功插入10W条数据耗时:1979 
成功插入10W条数据耗时:1730 
成功插入10W条数据耗时:1643 
成功插入10W条数据耗时:1665 
成功插入10W条数据耗时:1622 
成功插入10W条数据耗时:1624 
成功插入10W条数据耗时:1779 
成功插入10W条数据耗时:1698 
插入100W数据共耗时:19003

实验结果:

使用JDBC批处理,开启事务,平均每 1.9 秒插入 十万 条数据

3 总结

能够看到,在开启事务下 JDBC直接处理 和 JDBC批处理 均耗时更短。

Mybatis 轻量级框架插入 , mybatis在我这次实验被黑的可惨了,哈哈。实际开启事务以后,差距不会这么大(差距10倍)。大家有兴趣的可以接着去测试 
        JDBC直接处理,在本次实验,开启事务和关闭事务,耗时差距5倍左右,并且这个倍数会随着数据量的增大而增大。因为在未开启事务时,更新10000条数据,就得访问数据库10000次。导致每次操作都需要操作一次数据库。 
        JDBC批处理,在本次实验,开启事务与关闭事务,耗时差距很微小(后面会增加测试,加大这个数值的差距)。但是能够看到开启事务以后,速度还是有提升。

结论,设计到大量单条数据的插入,使用JDBC批处理和事务混合速度最快 
         实测使用批处理+事务混合插入1亿条数据耗时:174756毫秒


借用

JAVA JDBC大数据量导入Mysql

分别是:

           不用批处理,不用事务;

           只用批处理,不用事务;

           只用事务,不用批处理;

           既用事务,也用批处理;(很明显,这个最快,所以建议在处理大批量的数据时,同时使用批处理和事务)