您的位置:首页 > 其它

批量插入数据之程序优化

2013-10-13 02:57 417 查看
最近遇到一个问题:我的程序需要向某张表中导入一万条数据,如何提高其效率?

在代码层面,下面两种方式是比较常见的:

使用Statement对象

使用PreparedStatement对象

执行插入的代码如下:
public void insertByStatement(String userName,String password){
Connection conn=BaseDao.getInstance().getConnection();
Statement statement=null;
try {
statement=conn.createStatement();
String sql="insert into user_info (user_name,user_pass) values('"+userName+"',"+"'"+password+"')";
int i=statement.executeUpdate(sql);
if(i<=0){
throw new SQLException("插入失败!");
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
BaseDao.getInstance().closeAll(null, statement, null);
}
}

public void insertByPreparedStatement(String userName,String password){
Connection conn=BaseDao.getInstance().getConnection();
PreparedStatement ps=null;
try {
String sql="insert into user_info (user_name,user_pass) values(?,?)";
ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
for (int i = 0; i < 2500; i++) {
ps.setString(1, userName);
ps.setString(2, password);
ps.addBatch();
}
ps.executeBatch();
} catch (SQLException e) {
e.printStackTrace();
}finally{
BaseDao.getInstance().closeAll(null, ps, null);
}
}


下面分为单线程和多线程两种思路来测试:

单线程情况:

使用statement耗时218s。

try {
conn.setAutoCommit(false);

for(int i=1;i<=10000;i++){
new PostsDao().insertByStatement("test", "test");
}
conn.commit();
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}


使用preparedstatement批处理耗时8s。

try {
conn.setAutoCommit(false);

new PostsDao().insertByPreparedStatement("lemon", "lemon");
conn.commit();
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}


多线程(4个线程,每个线程插入2500条)情况下:

使用Statement耗时61s,本文略去代码。

使用PreparedStatement批处理耗时4s,代码如下:

try {
conn.setAutoCommit(false);
ThreadPoolExecutor threadPool2 = new ThreadPoolExecutor(4, 4, 0,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
threadPool2.execute(new ExecuteCallableThread());
threadPool2.shutdown(); //关闭后不能加入新线程,队列中的线程则依次执行完
while(threadPool2.getPoolSize()!=0);
System.out.println("main thread end!");
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}


本文仅仅在代码层面做了优化,可以看出,在一次性大量地插入数据时,PreparedStatement对象的executeBatch()和多线程的效率是比较好的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: