LAZYモードのone-to-many問題:FetchMode.JOIN でHibernate Criteriaクエリのパフォーマンス改善 | fetch 戦略

2010/11/12 11:55Update
TAGS: Hibernate | LAZYロード | 遅延ロード | one-to-many | HQL | Criteria | クエリ | fetch | FetchMode | チューニング

LAZYモードのone-to-manyのN+1問題について

問題の提出


1)1対多関係のテーブル同士のマッピングにLAZY(遅延)ロード設定の必要性。
  Hibernateでは、オブジェクト(Entity)を取得するのに、自動的に関連するオブジェクトを取りに行きます。そのため、データベースに多くの問い合わせが行われることになり、パフォーマンスが低下する恐れがあります。
  LAZY(遅延)ロードは、関連するオブジェクトのロードを最初にアクセルされるまで遅延させ、利用されていないオブジェクトに、データベースへの問い合わせを行わないようにしていますので、リソースの節約やパフォーマンスを向上します。
  Hibernate究明 - Hibernate のLAZYロード
2)子側(多側)オブジェクトが利用される時のN+1問題
  LAZY(遅延)ロードは、オブジェクトが初めて利用される時、データの取得を行い、データベースへの問い合わせSQLが発行されます。1対多の場合、N件の子データを取得するのに、N件のSQL文が発行されてしまいます。

結果


不必要なSQLが多く発行されてしまうことで、データベースに多大な負荷をかけることになります。

解決策


1)Hibernate HQLクエリ場合の解決策
Hibernate HQLクエリ join fetch でパフォーマンス改善 | fetch 戦略

2)Hibernate Criteriaクエリ場合の解決策

■one-to-many定義例
Father.hbm.xml(抜粋)
<set name="sonSet" cascade="all" inverse="true" fetch="join">
    <key column="FATHER_ID"/>  
    <one-to-many class="test.array.Son"/>  
</set>


■Criteriaクエリ例
List <Father> fatherList = session.createCriteria(Father.class)
       .setFetchMode("sonSet",FetchMode.JOIN)
       .list();

※注意:Hibernate HQLクエリ join fetch戦略と同じ、ここで取得したfatherListですが、データが重複し、サイズは子分のデータ数になってしまいます。


参考資料


Hibernate HQLクエリ - JOINによる結合

有关作者
Syboos.jp編集長AJavaやオープンソース情報の執筆、Webサイトの開発や運営全般の業務に携わる。

Sponsored Link


Comments

用户名 (required)

Email (will not be published) (required)

URL

Evaluation