向MySQL插入100w条数据,该怎么做?
使用MySQL存储过程插入
那么从sql层面上我们该怎么插入100万条数据呢,无脑直接写个循环?那就使用存储过程试试看吧
DROP PROCEDURE IF EXISTS proc_insert()
DELIMITER $
CREATE PROCEDURE pro_insert2()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i<=1000000 DO
INSERT INTO student VALUES(i,马老师,1970-02-02,广东深圳,60,60,60);
SET i = i+1;
END WHILE;
END $
调用该存储过程后执行时间如下
JDBC往数据库中普通插入方式
同样先来个粗暴的100万次for循环,代码如下
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* @author admin
* @version 1.0.0
* @ClassName InsertForDemo.java
* @createTime 2020年12月06日 15:17:58
*/
public class InsertForDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
long start = System.currentTimeMillis();
Connection con = SqlTools.getConnection();
System.out.println(con);
String sql = "insert into emp (uid,name,age,hiredate,salary,deptno) values(?,?,?,?,?,?)";
PreparedStatement ps = con.prepareStatement(sql);
for (int i = 0; i < 1000000; i++) {
ps.setString(1, SqlTools.getTrimUUID());
ps.setString(2, SqlTools.getChineseName());
ps.setInt(3, SqlTools.getNum(18, 60));
ps.setString(4, SqlTools.getCurrTime());
ps.setInt(5, SqlTools.getNum(5000, 500000));
ps.setInt(6, SqlTools.getNum(1, 50));
ps.execute();
}
con.close();
long end = System.currentTimeMillis();
System.out.println("插入100w条数据,for循环耗时:" + (end - start) + "ms");
}
}
执行用时653550ms 在讨论批量处理之前,先说说遇到的坑。MySQL驱动jar包,使用过低版本(5.1.13以下)会导致停止掉java程序后,mysql还在不断的往数据库中插入数据,最后不得不停止掉数据库服务才停下来…
使用事务批处理提交方式
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class InsertDataByTxDemo {
// insert into emp values (uid,name,age,hiredate,salary,deptno)
public static void main(String[] args) throws SQLException, ClassNotFoundException {
Connection con = SqlTools.getConnection();
String sql = "insert into emp values(?,?,?,?,?,?)";
try {
con.setAutoCommit(false);
PreparedStatement pst = con.prepareStatement(sql);
long start = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
long start2 = System.currentTimeMillis();
// 每一轮插入10万条
for (int j = 0; j < 100000; j++) {
pst.setString(1, SqlTools.getTrimUUID());
pst.setString(2, SqlTools.getChineseName());
pst.setInt(3, SqlTools.getNum(18, 60));
pst.setString(4, SqlTools.getCurrTime());
pst.setInt(5, SqlTools.getNum(5000, 50000));
pst.setInt(6, SqlTools.getNum(1, 50));
pst.addBatch();
}
pst.executeBatch();
pst.clearBatch();
con.commit();
long end2 = System.currentTimeMillis();
System.out.println("第" + (i + 1) + "轮执行时间:" + (end2 - start2) + "ms");
}
long end = System.currentTimeMillis();
System.out.println("总耗时:" + (end - start) + "ms");//168662ms
} catch (SQLException e) {
e.printStackTrace();
} finally {
con.close();
}
}
}
显然批处理事务提交的效果还不错。
