MySQL批量插入数据的几种方法

时间:2021-03-06 00:42:41

最近公司要求测试数据库的性能,就上网查了一些批量插入数据的代码,发现有好几种不同的用法,插入同样数据的耗时也有区别

别的先不说,先上一段代码与君共享

方法一:

package com.bigdata;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class TestBigData {

	/**
	 * @param args
	 * @throws Exception 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public static void main(String[] args) throws Exception {
		//--------------------------------连接数据库----------------------
		String driver="com.mysql.jdbc.Driver";
		String url="jdbc:mysql://127.0.0.1:3306/test";
		String user="root";
		String password="root";
		
		//1、新建驱动
		Driver driverInstance = (Driver) Class.forName(driver).newInstance();
		//2、注册驱动
		DriverManager.registerDriver(driverInstance);
		//3、获取连接
		Connection conn = DriverManager.getConnection(url, user, password);
		
		//----------------------对数据库进行操作-------------------
		//记录开始时间
		Long begin=System.currentTimeMillis();
		//-----------插入数据----------
		//sql语句前缀
		String sqlPre="insert into tb_big_db (count,create_time,random) values ";
		StringBuffer sb = new StringBuffer();
		//设置事务为非自动提交
		conn.setAutoCommit(false);
		//使用PrepareStatement更好
		PreparedStatement pstate = conn.prepareStatement("");
		
		//--------------------------十万条数据-------------
		//设置外循环,总提交事务的次数
		for(int i=0;i<100;i++){
			for(int j=0;j<10000;j++){
				//构建sql后缀
				sb.append("("+j*i+",SYSDATE(),"+i*j*Math.random()+"),");
			}
			//构建完整的sql
			String sql = sqlPre + sb.substring(0, sb.length()-1);
			//添加sql
			pstate.addBatch(sql);
			//执行sql
			pstate.executeBatch();
			//提交事务
			conn.commit();
			//清空StringBuffer上一次添加的sql语句
			sb = new StringBuffer();
		}
		//大循环完毕,关闭连接
		pstate.close();
		conn.close();
		//结束时间
		Long end = System.currentTimeMillis();
		System.out.println("10万条数据,插入数据库耗时:"+(end-begin)+"ms");
	}

}

 耗时:1952ms

说明:这速度,不堪入目啊,公司的数据库,不管从硬件还是软件来看,都不行呐。

方法二:

package com.bigdata;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class TestBigData2 {

	public static void main(String[] args) throws Exception{
		//--------------------------------连接数据库----------------------
		String driver="com.mysql.jdbc.Driver";
		String url="jdbc:mysql://127.0.0.1:3306/test";
		String user="root";
		String password="root";
		
		//1、新建驱动
		Driver driverInstance = (Driver) Class.forName(driver).newInstance();
		//2、注册驱动
		DriverManager.registerDriver(driverInstance);
		//3、获取连接
		Connection conn = DriverManager.getConnection(url, user, password);
		
		//-----------------------------------操作数据库-----------------
		//记录开始时间
		Long begin = System.currentTimeMillis();
		
		//动态sql语句
		String sql = "insert into tb_big_db (count,create_time,random) values (?,SYSDATE(),?)";
		//设置事务为非自动提交
		conn.setAutoCommit(false);
		//预编译sql
		PreparedStatement pstate = conn.prepareStatement(sql);
		//外循环10次
		for(int i=0;i<10;i++){
			//内循环10000次
			for(int j=0;i<1000;j++){
				pstate.setLong(1, i*j);
				pstate.setLong(2, i*j);
				//添加到批处理上
				pstate.addBatch();
			}
			//批处理
			pstate.executeBatch();
			//提交
			conn.commit();
		}
		//关闭
		pstate.close();
		conn.close();
		//结束时间
		Long end = System.currentTimeMillis();
		System.out.println("插入10万条数据,耗时:"+(end-begin)+"ms");
	}
}

 耗时:未知,原因是我用这个方法测试的时候,居然给我报内存溢出异常,说明这个方法需要的内存大,耗时高,所以我和上面的方法一做了个对比。

由于2个方法都用来prepareStatement类,该类在执行sql语句之前会对其进行预编译,就是说先把sql准备好先,用到的时候就直接用就可以了

方法一:通过代码分析,可以明显看到,方法一种的sql语句通过拼接成10条sql语句,故数据库执行语句时,只要执行10条就好

方法二:可以看出,它每循环一次,就要addBach()一次,速度变得更加慢,有10000条就addBatch()一万次,再批处理10次,所以速度变得慢是理所当然的