我正在按照这里列出的hibernate教程http://docs.jboss.org/hibernate/orm/5.1/quickstart/html_single/#tutorial-native。为什么hibernate在获取较少的行数时速度较慢?
我修改了使用本地mysql作为数据库的代码。之后,我用10000行填充数据库表。
我比较了两种类型的DB读取的延迟 - 一种是通过hibernate原生查询;其他通过直接JDBC并从ResultSet创建对象。
我发现很奇怪,看到与我的自定义JDBC和Java对象映射实现相比,hibernate非常慢。当获取的行数低于10000时会发生这种情况。例如,使用我的方法获取10-100行需要3-18ms,而休眠需要280-320ms左右。但是,当我尝试获取> 10K行时,hibernate变得高效。
有人可以请解释什么hibernate做这导致这么多的延迟?
我的hibernate.cfg.xml看起来像下面
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.url">jdbc:mysql://localhost:3306/fquick-task-manager?useSSLx`=false</property>
<property name="connection.username">root</property>
<property name="connection.password"/>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">15</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="org/hibernate/tutorial/hbm/Event.hbm.xml"/>
</session-factory>
</hibernate-configuration>
我的测试功能看起来像下面
public void testBasicUsage() {
// Using JDBC
Session session = sessionFactory.openSession();
session.beginTransaction();
String queryStr = "";
try {
long start = System.currentTimeMillis();
Statement statement = ((SessionImpl) session).connection().createStatement();
queryStr = "select * from Events where EVENT_ID < 10";
ResultSet rs = statement.executeQuery(queryStr);
List<Event> events = new ArrayList<Event>();
while (rs.next()) {
Long eventId = rs.getLong("EVENT_ID");
String title = rs.getString("title");
Date myDate = rs.getDate("EVENT_DATE");
Event event = new Event(eventId,title ,myDate);
events.add(event);
}
long end = System.currentTimeMillis();
long timeTaken = end - start;
System.out.println("Query took " + timeTaken + "ms");
} catch (SQLException e) {
System.out.println("Error in statement creation");
}
session.getTransaction().commit();
session.close();
// Using Hibernate
session = sessionFactory.openSession();
session.beginTransaction();
queryStr = "select * from Events where EVENT_ID > 20 & EVENT_ID < 30";
long start3 = System.currentTimeMillis();
session.createSQLQuery(queryStr).list();
long end3 = System.currentTimeMillis();
long timeTaken3 = end3 - start3;
System.out.println("Query took " + timeTaken3 + "ms");
session.getTransaction().commit();
session.close();
}
我试过这两件事情。获取相同的一组行,以及不同组的10行,50行,100行组合。结果是一样的。在数据库中花费的时间在每次5ms以内。休息是在ORM中度过的。我有兴趣了解休眠情况下的时间分配。在持久化上下文中保存对象需要多少时间,制作对象有多少时间,以及为什么在行数较少的情况下执行速度较慢。 –