在写完上一篇文章之后,在使用过程中慢慢发现一些问题,比如说数据入库很慢,10W的数据分10个文件入库大概需要两三分钟,如下图
这是我忍受不了的,所以我寻思着如何优化该程序,提高入库性能。因此我对JDBC数据入库的几种方法做了一个对比,在大量的实验下,发现了如下的规律:
1、使用statement耗时最长;
2、使用PreparedStatement耗时明显缩短;
3、使用PreparedStatement + 批处理耗时暂时耗时最少。
针对我的小程序,入库的表所需要的字段有上百个,我懒得去拼字符串,于是就选择Statement+批处理来处理,关键代码如下:
if(conn == null) {
conn = dbutil.getConnection();
}
pre = conn.createStatement();
conn.setAutoCommit(false);
while (line_record != null) {
if(line_record.indexOf("cdrid") != -1) {
line_record = buf.readLine();
continue;
}
// 解析每一条记录
sql = "INSERT IGNORE INTO " + tablename + " VALUES('";
String[] fields = line_record.split(DELIMITERS);
//对Insert语句的合法性进行判断
if(fields.length != colCount){
line_record = buf.readLine();
System.out.println("要插入的数据列数和表的数据列不相匹配,停止执行");
continue;
}
for (int i = 0; i < fields.length; i++) {
sql += fields[i];
if (i < fields.length - 1) {
sql += "','";
}
}
sql += "');";
// 在控制台输出SQL语句
// System.out.println(sql);
//执行SQL语句
pre.addBatch(sql);
rowCount++;
line_record = buf.readLine();
if (rowCount >= rc) {
break;
}
}
pre.executeBatch();
conn.commit();
pre.close();
然而程序入库的效率并没有显著的提高,最后,我在批量执行500条Sql的时候提交一次,代码如下:
if(rowCount % 500 == 0) {
pre.executeBatch();
conn.commit();
// pre.clearBatch();
}
这里的数字是自己定的,根据Java虚拟机大小来设定不同的值,这里的clearBatch()执行不执行都可以,在设定为100的时候,效率如下:
回顾本文最开始10W条数据分十个文件入库,效率明显提升了不少。