锁定老帖子 主题:Hibernate,JDBC性能探讨
该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-08-20
最后修改:2010-12-01
今天原打算研究一下Hibernate 1+N问题,却发现了一个Really Amazing的效率问题,问题如下,希望大牛可以解释一下: 1、简单描述一下测试中表结构(我用Mysql数据库),表结构如下图
2、如下代码,简单调运JDBC测试插入10000条数据花费时间 public class DB { public static Connection getConn() { Connection conn = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/hibernate?user=root&password=root"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; } public static Statement getStmt(Connection conn) { Statement stmt = null; try { if(conn != null) { stmt = conn.createStatement(); } } catch (SQLException e) { e.printStackTrace(); } return stmt; } public static void main(String[] args) throws SQLException { Statement stmt = getStmt(getConn()); Date start = new Date(); for(int i = 0 ; i < 10000 ; i ++) { String sql = "insert into corporation(name,type) value('Tibco','IT')"; stmt.executeUpdate(sql); } System.out.println("Total spent " + (new Date().getTime() - start.getTime())); } }
运行时间如下 Total spent 249531 这个时间我觉得是比较合理的执行一条SQL花费25毫秒左右,之前有关效率方面的测试和这个结果差不多
3. 下面给出Hibernate中测试时间的代码,先给出Hibernate配置代码 3.1 Corporation对应的Annotation配置类 @Entity public class Corporation { private int id; private String name; private String type; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } } 3.2 hibernate.cfg.xml配置信息 <hibernate-configuration> <session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost/hibernate</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <property name="connection.pool_size">1</property> <property name="current_session_context_class">thread</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <property name="show_sql">true</property> <property name="format_sql">true</property> <property name="hbm2ddl.auto">update</property> <mapping class="com.kylin.test.Corporation"/> </session-factory> </hibernate-configuration> 3.3给出测试代码 package com.kylin.test; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; public class AllTest { private static SessionFactory sessionFactory; @BeforeClass public static void beforeClass(){ sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); } @AfterClass public static void afterClass() { sessionFactory.close(); } @Test public void testExportTable() { new SchemaExport(new AnnotationConfiguration().configure()).create(true, true); } @Test public void saveCorporation() { Date start = new Date(); Session session = sessionFactory.getCurrentSession(); session.beginTransaction(); for(int i = 0 ; i < 10000 ; i ++) { Corporation c = new Corporation(); c.setName("Tibco"); c.setType("IT"); session.save(c); } session.getTransaction().commit(); System.out.println("Total spent " + (new Date().getTime() - start.getTime())); } }
如上saveCorporation()方法就是Hibernate想数据库中插入10000条数据的部分,这个结果确实令我吃惊,如下 Total spent 8781 我测试了多次这个时间都是8700毫秒左右,所以这个时间应该准确。 249531 / 8781 = 28.41,28倍,的确是28倍 4、分析一下 之前比较过Cassandra(分布式数据库)与Mysql的存储效率差别时发现关系数据库存储的SQL操作效率相当低,而Hibernate解决的是可以面向对象的操作关系数据库,所以我个人一直以为,Hibernate操作数据库的效率一定更低,但结果却恰恰相反,而且与我的之前的理解相差很大,所以我可以肯定的是Hibernate在数据操作效率上也有一定的技巧,大家谁知道可以说说。
PS。。本来还想再分析分析,但是周末了,不想再多呆在公司…… 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-08-20
估计hibernate是批量插入吧。看一下他执行的sql就明白了
|
|
返回顶楼 | |
发表时间:2010-08-20
batch啊batch
jdbc改成batch试试 |
|
返回顶楼 | |
发表时间:2010-08-20
出了batch 以外
jdbc 插入的代码写也有问题。 你那个写法, 每个insert 都要启动和提交一个事务 调用 conn.startTranscation() 然后在执行 insert 最后 conn.commit() 改成这样, jdbc 估计就比hibernate 快10倍了 |
|
返回顶楼 | |
发表时间:2010-08-21
hibernate不可能比jdbc快的。
如楼上几位所言: 1、batch 2、事务 3、PreparedStatement 4、String sql往外放(这个影响较小) |
|
返回顶楼 | |
发表时间:2010-08-21
hibernate跑起来不可能比Mysql快的。应该是楼主的jdbc插入有问题。或者是hibernate默认的是批量插入。应该看下他的代码就知道了。
|
|
返回顶楼 | |
发表时间:2010-08-21
呵呵,一叶障目不见泰山!
|
|
返回顶楼 | |
发表时间:2010-08-21
要看你组织的SQL了, Hibernate无论如何 也没有SQL快,呵呵呵, 至少它要浪费一步时间去生成SQL,然后再交给DB,呵呵呵呵
|
|
返回顶楼 | |
发表时间:2010-08-21
JDBC 1秒 1万条简单sql是没有问题
你batch 10000 |
|
返回顶楼 | |
发表时间:2010-08-21
最后修改:2010-08-21
hibernate 底层就是Jdbc 她不可能超越JDBC
只是hibernate漠然有优化 如果你的HDBC很垃圾 那自然hibernate快 如果都是最优那JDBC原始肯定快 但是要求程序员高 |
|
返回顶楼 | |