我正在按照這裏列出的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中度過的。我有興趣瞭解休眠情況下的時間分配。在持久化上下文中保存對象需要多少時間,製作對象有多少時間,以及爲什麼在行數較少的情況下執行速度較慢。 –