锁定老帖子 主题:Hibernate,JDBC性能探讨
该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-08-21
你的jDBC肯定是自动提交事务了
可能每插入一条就提交一次 而hibernate只执行了一次提交 |
|
返回顶楼 | |
发表时间:2010-08-21
最后修改:2010-08-21
今天闲得蛋疼,新自试了一遍。哈哈
不知你在什么配置情况下操作。因为结果是4分多钟。对于此结论很是惊奇,因为以前做过数据同步的东西,于是马上亲自验证,数据库和测试参数和你的都一样。 先说结果:我的测试最慢的只用了2.6秒。Statement最慢,PrepareStaement快了5秒钟,Batch和PrepareStatement并没有实质性的提高,只是一小点(这个倒是让我奇怪)。从一万到十万数据量都做过测试,但变化不大。我一直认为Batch会提高不少数量级的,可是结果让我失望,也不知哪写得不对,大家可以评点一下代码。 直接pringln 10000的一些对比数据: 清空表 普通的Statement插入数据: 插入数据量:10000 <运行时间: 2.656 秒> 运行时间:2656 毫秒 2.656 ================================ 清空表 通过PrepareStatement插入数据: 插入数据量:10000 <运行时间: 2.156 秒> 运行时间:2156 毫秒 2.156 ================================ 清空表 用批处理插入数据: 批量更新成功 10000 条记录! <运行时间: 2.078 秒> 运行时间:2078 毫秒 2.078 ================================ 代码如下: Java代码 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()); for (int i = 0; i < TEST_NUM; i++) { int index = 1; ps.setString(index++, "Peter Wei"); ps.setString(index++, "test"); num += ps.executeUpdate(); } 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("================================"); } } |
|
返回顶楼 | |
发表时间:2010-08-21
现在鼠辈横行啊!
殊不知: Hibernate也是封装的JDBC。就像Windows和DOS操作系统的关系。 现在只知SSH不知Java\Servlet的太多了 |
|
返回顶楼 | |
发表时间:2010-08-21
你们真是闲得蛋疼啊(我也是)
hibernate内部也是执行JDBC 就好像汽车对车轮说:我跑得比你快 真无聊啊... |
|
返回顶楼 | |
发表时间:2010-08-21
就像Windows和DOS操作系统的关系。
_______________________ 晕倒,Windows和Dos是这种关系? |
|
返回顶楼 | |
发表时间:2010-08-21
hibernate底层还是jdbc
你这jdbc代码写的太没效率了 |
|
返回顶楼 | |
发表时间:2010-08-21
pujia12345 写道 现在鼠辈横行啊!
殊不知: Hibernate也是封装的JDBC。就像Windows和DOS操作系统的关系。 现在只知SSH不知Java\Servlet的太多了 ... ... 可能你说的是Win3.x 吧... |
|
返回顶楼 | |
发表时间:2010-08-21
完全不可理喻的对比,单个插入和批量插入的对比。
就如同,堵车的时候,我走路比汽车快。 这个案例有意义么? 要不是无聊,要不就是无耻 |
|
返回顶楼 | |
发表时间:2010-08-21
最后修改:2010-08-21
为这个问题自己也一直挺郁闷的, 出现这种问题只能怪自己 jdbc 没有写好!
有 jdbc 方面经验的帮忙看下我这个 blog: http://yhailj.iteye.com/admin/blogs/619890 |
|
返回顶楼 | |