今天在Javaeye论坛上看到有位网友得出结论:主题:Hibernate性能 - 30倍普通SQL操作 - 探讨 地址:[url]http://www.iteye.com/topic/743613 [/url].贴子中说JDBC测试插入10000条数据花费时间:Total spent 249531毫秒.而且贴子还说:这个时间我觉得是比较合理的执行一条SQL花费25毫秒左右,之前有关效率方面的测试和这个结果差不多。
[b][color=red]不知他在什么配置情况下操作。因为结果是4分多钟[/color][/b]。对于此结论很是惊奇,因为以前做过数据同步的东西,于是马上亲自验证,数据库和测试参数和他的都一样。
先说结果:我的测试最慢的只用了2.6秒。Statement最慢,PrepareStaement快了5秒钟,[color=red]Batch和PrepareStatement并没有实质性的提高,只是一小点(这个倒是让我奇怪)。[/color]从一万到十万数据量都做过测试,但变化不大。我一直认为Batch会提高不少数量级的,可是结果让我失望,也不知哪写得不对,大家可以分析一下代码。
------------------------------------------------------------
[color=red]结果已出来,是默认的Mysql不是InnoDB,所以没有事务,所以之前测的没有本质变化。实际上在事务下,Batch能提高数量级的提高。[/color]
直接pringln 10000的一些对比数据:
清空表
普通的Statement插入数据:
插入数据量:10000
<运行时间: 2.656 秒>
运行时间:2656 毫秒
2.656
================================
清空表
通过PrepareStatement插入数据:
插入数据量:10000
<运行时间: 2.156 秒>
运行时间:2156 毫秒
2.156
================================
清空表
用批处理插入数据:
批量更新成功 10000 条记录!
<运行时间: 2.078 秒>
运行时间:2078 毫秒
2.078
================================
代码如下:
[b][color=red]不知他在什么配置情况下操作。因为结果是4分多钟[/color][/b]。对于此结论很是惊奇,因为以前做过数据同步的东西,于是马上亲自验证,数据库和测试参数和他的都一样。
先说结果:我的测试最慢的只用了2.6秒。Statement最慢,PrepareStaement快了5秒钟,[color=red]Batch和PrepareStatement并没有实质性的提高,只是一小点(这个倒是让我奇怪)。[/color]从一万到十万数据量都做过测试,但变化不大。我一直认为Batch会提高不少数量级的,可是结果让我失望,也不知哪写得不对,大家可以分析一下代码。
------------------------------------------------------------
[color=red]结果已出来,是默认的Mysql不是InnoDB,所以没有事务,所以之前测的没有本质变化。实际上在事务下,Batch能提高数量级的提高。[/color]
直接pringln 10000的一些对比数据:
清空表
普通的Statement插入数据:
插入数据量:10000
<运行时间: 2.656 秒>
运行时间:2656 毫秒
2.656
================================
清空表
通过PrepareStatement插入数据:
插入数据量:10000
<运行时间: 2.156 秒>
运行时间:2156 毫秒
2.156
================================
清空表
用批处理插入数据:
批量更新成功 10000 条记录!
<运行时间: 2.078 秒>
运行时间:2078 毫秒
2.078
================================
代码如下:
package test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import com.fastbo.util.Clock;
import com.fastbo.util.ConnectionFactory;
import com.fastbo.util.DbUtil;
/**
* Description: Jdbc相关性能测试,batch处理,PrepareStatement,Statement等。
*
* <p>
* Mysql数据库:表结构为简单的id,name(varchar:255),type(varchar:255)字段,id自增
* </p>
*
* @author Peter Wei Email: <a href="mailto:weigbo@163.com">weigbo@163.com </a>
*
* @version 1.0 2010-8-21
*/
public class JdbcTest {
/**
* 测试数据量
*/
public static int TEST_NUM = 10000;
/**
* 批处理大小
*/
public static int BATCH_SIZE = 300;
/**
* 清空数据表
*
* @param con
*/
public static void clear(Connection con) {
PreparedStatement ps = null;
StringBuffer buff = new StringBuffer();
try {
buff.append("truncate table bobo");
ps = con.prepareStatement(buff.toString());
ps.executeUpdate();
System.out.println("清空表");
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtil.close(ps);
}
}
/**
* 普通的Statement插入数据
*
* @param con
*/
public static int add(Connection con) {
Statement stmt = null;
int num = 0;
String sql = "insert into bobo(name,type) values('Peter Wei','test')";
try {
stmt = con.createStatement();
for (int i = 0; i < TEST_NUM; i++) {
num += stmt.executeUpdate(sql);
}
System.out.println("插入数据量:" + num);
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtil.close(stmt);
}
return num;
}
/**
* 用PrepareStatement插入数据
*
* @param con
*/
public static void addByPrepareStatement(Connection con) {
PreparedStatement ps = null;
StringBuffer buff = new StringBuffer();
int num = 0;
try {
buff.append("insert into bobo(name,type)");
buff.append(" values(?,?)");
ps = con.prepareStatement(buff.toString());
con.setAutoCommit(false);
for (int i = 0; i < TEST_NUM; i++) {
int index = 1;
ps.setString(index++, "Peter Wei");
ps.setString(index++, "test");
num += ps.executeUpdate();
}
con.commit();
con.setAutoCommit(true);
System.out.println("插入数据量:" + num);
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtil.close(ps);
}
}
/**
* 用批处理插入数据
*
* @param con
*/
public static void addByBatch(Connection con) {
PreparedStatement ps = null;
StringBuffer buff = new StringBuffer();
int sum = 0;
int[] num = null;
try {
buff.append("insert into bobo(name,type) values(?,?)");
con.setAutoCommit(false);
ps = con.prepareStatement(buff.toString());
for (int i = 0; i < TEST_NUM; i++) {
int index = 1;
ps.setString(index++, "Peter Wei");
ps.setString(index++, "test");
ps.addBatch();
if (i != 0 && i % BATCH_SIZE == 0) {
num = ps.executeBatch();
sum += num.length;
con.commit();
// System.out.println("batch:" + i);
}
}
num = ps.executeBatch();
sum += num.length;
con.commit();
con.setAutoCommit(true);
System.out.println("批量更新成功 " + sum + " 条记录!");
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtil.close(ps);
}
}
public static void main(String[] args) {
Connection con = ConnectionFactory.getConnection();
clear(con);
Clock c = new Clock();
// 普通的Statement插入数据
System.out.println("普通的Statement插入数据:");
c.start();
add(con);
c.stop();
System.out.println(c.toString());
c.readMilli();
System.out.println(c.read());
System.out.println("================================");
clear(con);
// 通过PrepareStatement插入数据
System.out.println("通过PrepareStatement插入数据:");
c = new Clock();
c.start();
addByPrepareStatement(con);
c.stop();
System.out.println(c.toString());
c.readMilli();
System.out.println(c.read());
System.out.println("================================");
clear(con);
// 用批处理插入数据
System.out.println("用批处理插入数据:");
c = new Clock();
c.start();
addByBatch(con);
c.stop();
System.out.println(c.toString());
c.readMilli();
System.out.println(c.read());
System.out.println("================================");
}
}