當試圖優化在傳統項目由Hibernate 4.2產生MySQ查詢速度慢,我發現下面的代碼生成近500 SQL查詢(許多重複):爲什麼hibernate會生成〜500個SQL查詢?
class MyDAO {
public List<Message> findMessages() {
Session session = MyHibernateUtils.openSession();
String queryStr = "SELECT DISTINCT m FROM Message m "
+ " LEFT JOIN fetch m.types types "
+ " LEFT JOIN fetch m.mainType mainType "
+ " LEFT JOIN fetch m.place place "
+ " LEFT JOIN fetch m.building building "
+ " LEFT JOIN fetch m.city city "
+ " LEFT JOIN fetch m.kind kind "
+ " LEFT JOIN fetch m.domain domain "
+ " LEFT JOIN fetch m.action action "
+ " LEFT JOIN fetch m.customParameterA customParameterA "
+ " LEFT JOIN fetch m.customParameterB customParameterB "
+ " LEFT JOIN fetch m.scheduleEvents scheduleEvents "
+ " LEFT JOIN fetch m.comments comments "
+ " LEFT JOIN fetch m.messageLastActivities messageLastActivities "
+ " LEFT JOIN fetch m.customListA customListA "
+ " LEFT JOIN fetch m.childEvents childEvents "
+ " LEFT JOIN fetch m.parentEvent parentEvent "
+ " WHERE ...";
List<Message> messages;
try {
session.getTransaction().begin();
Query query = session.createQuery(queryStr);
query.setTimeout(10);
messages = query.list();
session.getTransaction().commit();
} catch (RuntimeException e) {
session.getTransaction().rollback();
throw e;
} finally {
session.close();
}
return messages;
}
}
如何避免有這麼多SQL查詢?
我不知道它是否有幫助,但實體之間有許多onyToMany和manyToMany關係。
感謝您的幫助。
ORM框架大部分時間都是這樣工作的...他們需要額外啓動一個'SELECT * FROM table WHERE id = 1'找到相關的實體 –
@RaymondNijland不,他們沒有。那麼,在最糟糕的情況下,他們會這樣做,但這在大多數情況下都是可以避免的,而且在Hibernate中也是如此。只有一個非常天真的ORM會這樣做,因爲它會導致性能下降,並使框架變得毫無價值。 – Kayaman
至於OP,爲Hibernate啓用SQL日誌記錄(環顧四周,我不記得它是如何完成的),並查看*執行了哪些*查詢。這將允許您指出原因,這可能只是您需要修復的單個N + 1查詢。 – Kayaman