分类
WEB开发

Mysql批量执行sql语句优化

最近一个项目需要批量导入功能,开始时采用在服务端循环调用存储过程,一条一条插入的方式。项目完成交给客户后,客户反应导入速度太慢,于是开始查找原因。发现这种逐条调用存储过程插入的方式每秒钟大概处理50条,而客户一次导入超过5万条。于是开始优化。
逐条调用的方式,每操作一条记录,都有一次数据库的连接、释放过程,比较耗时,首先想到了用批量executeBatch语句。经过反复调试,最终65000条数据批量导入耗时20秒,以下是代码:

String activityId = "";
String phones = "";//这里是批量导入的手机号,英文逗号隔开的
Connection conn = null;
CallableStatement proc = null;
int[] ret = null;
try{
	conn = DriverManager.getConnection(ORA_URL, ORA_USER, ORA_PWD);//此处换成你自己的数据库连接信息
	//conn.setAutoCommit(false);
	proc = conn.prepareCall("{call pro_add_phone(?,?)}");
	String[] tempPhones = phones.split(",");
	for(String phone : tempPhones){
		if(phone != null && !phone.equals("")){
			proc.setString(1, activityId);
			proc.setString(2, phone);
			//proc.registerOutParameter(3, Types.INTEGER);
			proc.addBatch();
		}
	}
	ret = proc.executeBatch();
	//conn.commit();
}catch(SQLException ex2){
	System.out.println(ex2.toString());
	ex2.printStackTrace();
}catch(Exception ex){
	System.out.println(ex.toString());
}finally{
	try{
		if(proc!=null)
		proc.close();
		if(conn!=null)
		conn.close();
	}catch(SQLException ex1){
		System.out.println(ex1.getMessage());
	}
}

调试过程中遇到不少问题,记录如下:
1、这里用的Java连接包为:mysql-connector-java-5.1.30-bin.jar,刚开始用以上代码发现并不明显,发现是这个jar包版本太低,貌似不支持真正的批量执行(据说executeBatch内部依然是如条执行的)。
2、数据库连接url添加参数rewriteBatchedStatements=true
3、Can’t call executeBatch() on CallableStatement with OUTPUT parameters存储过程不能带输出参数,最后去掉了输出参数。
原创内容转载请保留出处GEEK笔记(http://www.geekapp.cn/)。

发表评论

电子邮件地址不会被公开。 必填项已用*标注