Java jdbc批量多线程读取CVS文件入库性能优化篇

来源:互联网 发布:开票软件的控制台 编辑:程序博客网 时间:2024/06/06 05:26

在写完上一篇文章之后,在使用过程中慢慢发现一些问题,比如说数据入库很慢,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条数据分十个文件入库,效率明显提升了不少。

1 0
原创粉丝点击