2009-11-05 15 views
8

NHibernateの遅延ロードについて聞いたことのほとんどは、それを使用しないよりも使用するほうが良いということです。ボトルネックを減らすために、データベースへのアクセスを最小限に抑えることが理にかなっているようです。しかし、トレードオフのないものはほとんどありません。確かに、あなたはvirtualのプロパティを持つように強制してデザインをわずかに制限します。しかし、一部の開発者は、頻繁に使用される特定のオブジェクトで遅延ロードをオフにすることに気づきました。いつNHibernateの遅延ロード機能を使用しないでください?

これは、レイジーローディングを使用してデータアクセスのパフォーマンスが低下するという明確な状況があるのか​​どうか疑問です。

私はNHibernateで永続化されたオブジェクトの1つを遅延ロードするのを避ける必要があるのはいつですか?

レイジーローディングの欠点は、単に追加の処理時間であるか、レイジーローディングをnhibernateしてもデータアクセス時間が増加することです(データベースへの追加ラウンドトリップなど)。

ありがとうございます!

答えて

19

データベースからのeagerローディングオブジェクトとlazyローディングオブジェクトの間の明確なパフォーマンスのトレードオフがあります。

熱心な読み込みを使用する場合は、大量のデータを1回のクエリで吸い取り、キャッシュすることができます。これは、アプリケーションの起動時に最も一般的です。あなたは、データベースの往復旅行のためにメモリ消費量を取引しています。

遅延読み込みを使用すると、1回のクエリで最小限の量のデータを吸い取ることができますが、その初期データに関連する詳細情報が必要な場合は、データベースへのクエリが多く必要になり、データベースのパフォーマンスヒットは、ほとんどのアプリケーションでパフォーマンスのボトルネックが発生します。

したがって、一般的には、「unit of work」全体に必要なデータを正確に取得する必要があります。場合によっては、ユーザーが必要なものを正確に把握していない可能性があります(ユーザーがウィザードなどを使って作業しているため)、そのような場合は遅延ロードに意味があります。

ORMを使用していて機能をすばやく追加して戻ってパフォーマンスを後で最適化する場合(これは非常に一般的なやり方です)、遅延ロードをデフォルトにすることが正しい方法です。後で(パフォーマンスプロファイリング/分析によって)オブジェクトを取得するクエリが1つあり、そのオブジェクトに関連するN個のオブジェクトを取得するためのN個のクエリがある場合、そのコードを変更して熱心な読み込みを使用してデータベースをN + 1回ではなく1回実行します(N + 1の問題はレイジーローディングのよく知られた欠点です)。

+0

しかし、プロジェクトが非常に大きくなった後にlazyloadingを使い始めると、多くのことを変えるのが遅れます。私は最良のアプローチは、あなたが1つのクエリでデータベースからフェッチする必要があるデータを見つけることだと思います。この方法では後者はこれらのオブジェクトをキャッシュできますが、lazyloadingを持つオブジェクトはキャッシュできません。 – Meysam

1

ショートバージョンはこれです:あなたが遅延ロードを使用する場合

  1. 開発が簡単です。自然なオブジェクト指向の方法でオブジェクトの関係をトラバースするだけで、求めるときに必要なものを得ることができます。
  2. パフォーマンスを求める前に、必要なものを見つけて、データベースへの1回の旅行でそれを求めるのが一般的です。

私たちは過去数年間、迅速な開発に力を注いできました。堅実なアプリケーションとユーザーベースができたので、私たちはデータアクセスを最適化しています。

+2

合計パフォーマンスが向上することがありますが、大きなオブジェクトグラフの読み込みが*明らかなパフォーマンスに影響することがあります。これはユーザーにとって大きな影響を与えることがあります。 –

+1

優れたポイント。基本を読み込みます。表示。 Ajaxは必要に応じて横断された値になります。 (例えば)。 – z5h

3

遅延ロードの通常のトレードオフは、データベースのヒット率を下げることですが、長期的にヒットします。 遅延読み込みがないと、オブジェクトグラフ全体を前面につかんで、大量のデータを一度に吸い取ることになります。これは潜在的に、あなたのUIの遅れを引き起こす可能性があるので、しばしば落胆します。しかし、共通のオブジェクトグラフ(単一のオブジェクトだけでなく、それ以外の場合でも問題ありません)があれば、よくアクセスし、上から下にアクセスすることになります。

たとえば、注文管理システムを実行している場合、要約画面のすべての注文のすべての行、またはすべての顧客情報をプルダウンすることはおそらくありません。レイジーローディングにより、これが起こらないようにします。

私はそれをオフラインで使っていないという良い例は考えられませんが、アプリケーションの初期化時にオブジェクトグラフを大量にロードしたい場合がありますラインをさらに下回る処理の遅れを回避する。

2

nhibernateを使用してデータベースアクセスを処理するクライアントとサーバーの間でWebサービスを使用している場合は、オブジェクトがシリアル化され、Webサービスを介して送信され、その後「オブジェクト」がオブジェクト関係は、追加のWebサービスを使用してデータベースサーバーへの新たなトリップを必要とします。そのような場合、遅延読み込みを使用するとあまりうまくいかないかもしれません。あなたが怠惰な読み込みをすると、あなたが取ったものを注意深く読んでください。これは簡単ではありません。データベース全体をフェッチすることになります。

0

多くのパフォーマンス上の問題がありますHibernateの間違ったローディング動作の設定に起因します。状況はNHibernateと全く同じだと思います。私のお勧めは、常に怠惰な関係を使用して、あなたのクエリでeager fetching statemetns(フェッチ結合など)を使用することです。これにより、多くのデータをロードすることがなくなり、多くのSQLクエリーを回避できます。

クエリで怠惰な関連付けをするのは簡単です。それはほぼ不可能です。

関連する問題