web-dev-qa-db-ja.com

Java Hibernateでのパフォーマンス関連の疑い)

一部のORMベースのプロジェクト(Hibernateなど)で、20を超える属性を持つオブジェクト全体ではなく、いくつかの列のみをフェッチしようとしているとします。私は"select attr1, attr2 from Entity "のようなHQLを書いています。私はHibernateを使用していないことを知っています。これは、結果をオブジェクト形式でのみ取得し、明示的にキャストする必要があるためです。しかし、それがデータベースの見込みから最適化を達成するための正しいアプローチになるのか、それとも私がコストを明示的にキャストしているのでコストは変わらないのでしょうか?

6
Logicalj

すべてのエンティティ属性を取得するときにパフォーマンスの問題が発生しない場合は、マイクロ最適化に時間を費やさないでください。

属性が非常に大きい場合を除いて、すべての列ではなく、特定の操作に本当に必要な列のみを選択しても、パフォーマンスに違いはありません。

本当に心配している場合は、それがパフォーマンスの問題を引き起こすと考えており、それらの問題を回避したい場合は、いくつかのテストを実行して(平均時間を取得するために多くの反復を使用)、すべての属性を取得するコストと、あなたが必要なもの。テストを書くのにあなたが思っているよりも短い時間で済みますし、あなたの決定を裏付けるデータを得るためにそれは価値があります。

想定しているパフォーマンスの問題を証明するためのデータを取得し、パフォーマンスの違いが大きいために違いが生じる場合特定のアプリケーションでの場合、改善方法の調査を開始することは理にかなっていますパフォーマンス。

7
Mike Partridge

Hibernateや他のORMツールは素晴らしいものであり、完全なアプリケーションへの道の80%を提供します。あなたの例では、attr1とattr2が列から読み取られたプリミティブ値である場合、Hibernateが何をしているのか気にしないので、ResultSetを自分で反復するときにHibernateなしで作業するとオーバーヘッドが発生する可能性があります。 attr1とattr2が結合の結果である場合は、結果のコレクションを遅延ロードすることができます。つまり、データが要求されるまで(トランザクションがまだ開いている場合)、変数はプロキシオブジェクトに読み込まれます。値を取得するデータベース。

しかしながら。 Hibernateは、かなり醜い(最適ではない)クエリをいくつか作成し、多くの場合、多くのクエリを使用します。 HibernateのロギングをDEBUGにすると、複数の選択として実行される単一のクエリであると予想したものが表示される場合があります。パフォーマンスがボトルネックになる可能性があるのはこの時点で(それが来るかどうかに応じて)、データソースに最適なようにモデル化されたすべての結合でJdbcTemplateを使用したほうがよいでしょう。

2つのテクニックを最終的に混合することは、問題なく一般的です。

いつものように、それが遅くなければ、修正しないでください!

2
JohnMark13

私はHibernateを利用していないことを知っています[...]

Hibernateは、完全なJavaオブジェクトを完全なデータベーステーブルにマッピングすることを想定している単なる自動ORMよりも少しだけです。クエリだけでなく、すべての操作のマッピングを提供します。挿入と削除は簡単に機能します。完全なオブジェクトをデータベースに挿入したくない場合でも、Hibernateにはレベル2キャッシュ(Ehcache)が付属しており、パフォーマンスが大幅に向上します。

必要なオブジェクトのみを選択することについて。 Hibernateにも改善が加えられています。たとえば、私OO開発者は、SQLとリレーションに精通しているデータベース開発者ではなく、オブジェクトモデルに精通しています。Hibernateは、よりオブジェクトに適したものを使用できるようにすることで、私の助けになります。クエリ言語(HQL、JPQL)。さらに、特定のテーブルを別のクラスにマップする方法がわからない場合でも、それを配列(または1つのクエリで複数のエントリが返される場合は配列のリスト)に変換します。 ResultSetを取得して繰り返す必要はありません。

もう1つの方法は、遅延フェッチを使用することです。データベースへの呼び出しは、実際にメソッドを呼び出したときにのみ行われます。特定のフィールドが必要ない場合は、それらを遅延として設定し、必要でない場合はフェッチされません。

最後の言葉として、Hibernateのような自動ORMツールは優れており、生産性を大幅に向上させると言わざるを得ませんが、これは特効薬ではありません。それらはすべてのシナリオに適しているわけではありません。特別なデータベース機能が必要な場合や、十分に複雑なドメインを扱っていない場合は、古き良きJDBCか、Springの代替であるJdbcTemplateが適しています。

0
m3th0dman

一部の列のみを選択する場合は、次のようにしますSelect new x.y.z.Object(c.column1, c.column2) FROM Object c

もちろん、これらの2つのフィールドのみを持つコンストラクターを宣言する必要があります。ログを分析すると、必要な列のみがDBからフェッチされていることがわかります。私が言える限り、これは明示的なフェッチの使用とともに完全に有効なユースケースです(このような最適化が必要になる場合があります)。

それが役に立てば幸い

0
Kemoda