4

NHibernate を使用して、さまざまなタイプのオブジェクトの大きなツリーをロードしています。マッピングは、table-per-subclass 戦略を使用して実装されます。少数のフィールド (NodeId、ParentId、NodeType) と、Node から継承して独自のフィールドを追加するいくつかのサブクラスのみを持つ基本クラス「Node」を定義しました。

このアプローチの実装は簡単で、パフォーマンスについて文句を言うことはできません。異なるタイプの 10,000 個のオブジェクトの大きなツリーが、1 回のラウンドトリップを使用して数百ミリ秒以内に私の古いマシンに取り込まれます。ただし、気になる点が 1 つあります。このような戦略では、ノード テーブルが、定義されたサブクラスに対応する他のすべてのテーブルと外部結合される複雑なクエリが生成されます。異なるサブクラスの数が少ない場合はこれで問題ありませんが、数が増えると OUTER JOIN の複雑さも増します。

クラスごとにテーブルを定義することは洗練されたオプションではないようで、基本クラスからデータを選択するときに動作が遅くなります (UNION のため)。他のオプションでは、データベース サーバーへの往復回数が増えるようです。

では、さまざまな種類のエンティティで構成される大規模なツリーを作成する場合のベスト プラクティスは何だと思いますか? サブクラスごとのテーブルよりも優れたものはありますか?

4

2 に答える 2

2

結合を防ぐために、table-per-classhirarchy 戦略を使用できます。次に、すべてのサブクラスが同じテーブルに存在し、識別子列で識別されます。

このアプローチを 15 のサブクラスに使用しました。

唯一の欠点は、サブクラスのプロパティに not null 制約を定義できず、これをコードで処理する必要があることです。

于 2011-05-17T16:37:40.807 に答える
2

ここでは、次の 2 つの問題を扱っています。

  1. 大きな階層をたどる。

  2. ラージ オブジェクト グラフ。

どちらも、ORM が問題を起こす領域です。ここでは ORM がボトルネックになるため、ボトルネックが発生した場合は、標準の ORM 機能を回避し、ストアド プロシージャにドロップダウンして重い作業を処理する必要がある場合があります。

ストアド プロシージャを使用すると、SQL の実行計画を活用して、問題を解決し、クエリのスロー ポイントを特定し、インデックス作成の機会を特定できます。

Nhibernate のドキュメントから(これは Nhibernate Forge がダウンしていたキャッシュです)

ボトルネックでは、手作業でコーディングされた ADO.NET を使用します。

システムのパフォーマンスが重要な領域では、一部の種類の操作 (一括更新/削除など) で直接 ADO.NET が役立つ場合があります。ただし、何かがボトルネックであることがわかるまでお待ちください。また、ダイレクト ADO.NET が必ずしも高速であると想定しないでください。直接 ADO.NET を使用する必要がある場合は、NHibernate ISession を開いてその SQL 接続を使用する価値があるかもしれません。そうすれば、同じトランザクション戦略と基礎となる接続プロバイダーを引き続き使用できます。

于 2011-04-11T19:11:06.163 に答える