今天抽空做了一下使用Jdbc对数据操作的实际性能。在平时开发过程中我们经常会使用Hibernate来操作数据库,所以我们很少会去使用批量插入数据。一般都是通过hibernate的insert、addSave等方法来一条条地插入数据。所以很少去考虑这个问题。下面是针对Jdbc进行的数据批量插入与逐条数据插入方法的实际情况:
package org.leaderbird.dbtest;
import java.sql.Connection;
import org.leaderbird.util.DbManager;
public class ExamOne {
private void batchAddSave(){
Connection oracleConn= null;
try{ oracleConn=DbManager.getConnection(DbManager.DATA_BASE_TYPE_ORACLE);
DbManager.execSQL(oracleConn,getSql());
}catch(Exception ex){
ex.printStackTrace();
}finally{
DbManager.closeConnection(oracleConn);
}
}
private void sigleAddSave(){
Connection oracleConn= null;
try{
oracleConn=DbManager.getConnection(DbManager.DATA_BASE_TYPE_ORACLE);
for(int i=0;i<2001;i++){
DbManager.execSQL(oracleConn,"insert into TEST values ('"+i+"','F"+i+"','"+i+"','"+i+")");
}
}catch(Exception ex){
ex.printStackTrace();
}finally{
DbManager.closeConnection(oracleConn);
}
}
public String getSql(){
StringBuffer sf= new StringBuffer();
sf.append("insert into TEST ");
for(int i=0;i<2000;i++){
sf.append("select "+i+",'F"+i+"',"+i+","+i+" from dual union ");
}
sf.append("select 100000,'F100000',100000,100000 from dual");
return sf.toString();
}
public static void main(String args[]){
ExamOne eo = new ExamOne();
long memory = 0L;
long time = 0L;
memory = Runtime.getRuntime().freeMemory();
time = System.currentTimeMillis();
eo.sigleAddSave();
System.out.println(System.currentTimeMillis() - time); System.out.println(memory - Runtime.getRuntime().freeMemory());
}
}
从上面的测试报告可以看出,使用jdbc的批量插入1000条数据所需的时间基本是逐条插入的0.4倍;而在插入2000条数据时几乎是后者的四分之一,在插入3000条数据时前者已超过了后者的五分之一。由此可以看出在执行效率上批量插入的速度是非常有优势的。当然在实际情况下也不是说这个批量可以是无限大的,它需要取决于我们的运行环境,如:应用服务器、数据库服务器。一般来说普通可以调到5000,我这测试过5000条数据时前者仅为后者的将近十分之一。在做1W条数据批量插入时,我这是内在通不过了。
另外一点大家可能看到在内在消耗方面,可能会有人说:在数据量大一些时批量插入的内在消耗比逐条插入所占用的内存要多,其实不然。批量操作是拼装了所有字符,所以总量看来来大一些,而拼逐是每操作一条就释放了先前的内存,它的执行是内存被告不停地创建与释放的循环,直到所有数据都操作完成。所以,后者的内存是不准确的。