最近一个项目需要批量导入功能,开始时采用在服务端循环调用存储过程,一条一条插入的方式。项目完成交给客户后,客户反应导入速度太慢,于是开始查找原因。发现这种逐条调用存储过程插入的方式每秒钟大概处理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笔记(https://www.geekapp.cn/)。