今天在Javaeye论坛上看到有位网友得出结论:主题:Hibernate性能 - 30倍普通SQL操作 - 探讨 地址:[url]http://www./topic/743613 [/url].贴子中说JDBC测试插入10000条数据花费时间:Total spent 249531毫秒.而且贴子还说:这个时间我觉得是比较合理的执行一条SQL花费25毫秒左右,之前有关效率方面的测试和这个结果差不多。
不知他在什么配置情况下操作。因为结果是4分多钟。对于此结论很是惊奇,因为以前做过数据同步的东西,于是马上亲自验证,数据库和测试参数和他的都一样。 先说结果:我的测试最慢的只用了2.6秒。Statement最慢,PrepareStaement快了5秒钟,Batch和PrepareStatement并没有实质性的提高,只是一小点(这个倒是让我奇怪)。从一万到十万数据量都做过测试,但变化不大。我一直认为Batch会提高不少数量级的,可是结果让我失望,也不知哪写得不对,大家可以分析一下代码。 ------------------------------------------------------------ 结果已出来,是默认的Mysql不是InnoDB,所以没有事务,所以之前测的没有本质变化。实际上在事务下,Batch能提高数量级的提高。 直接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("================================"); } } |
|