質問

データベース内の数百万件のレコードを定期的に(たとえば毎週)ループし、各行の結果に対してコードを実行する必要があるアプリケーションを作成しています。

テーブルが非常に大きいため、SomeObject.FindAll()を呼び出すと、140万行すべてを読み取り、SomeObject []のすべての行を返そうとしていると思われます。

SomeObject.FindAll()式を実行できる方法はありますが、よりDBMSに適した方法で値をロードしますか?

役に立ちましたか?

解決

FindAll()なし-推測したように、指定したタイプのすべてのインスタンスを一度にロードしようとします(NHibernateのセットアップ方法によっては、膨大な数のそれを行うためのSQLクエリ)。

遅延読み込みはオブジェクトのプロパティでのみ機能します。たとえば、すべてのSomeObjectContainerと一致するようにマップされたSomeObjectのリストをプロパティとして持つ永続型lazy="true"がある場合、 foreachを使用して、そのリストプロパティで<=>を実行すると、必要なものが得られます。デフォルトでは、NHibernateはリスト内の各要素に対してクエリを発行し、一度に1つだけをロードします。もちろん、読み取りキャッシュは非常に大きくなるので、おそらく大量にフラッシュする必要があります。

できることは、HQL(または埋め込みSQL)クエリを発行して、すべてのSomeObjectsのすべてのIDを取得し、FindByPrimaryKeyで関連するオブジェクトを1つずつフェッチすることです。繰り返しますが、特にエレガントではありません。

正直に言うと、そのような状況では、おそらくこれをストアドプロシージャのスケジュールされたメンテナンスジョブに変えます-データを操作するのではなく、オブジェクトで code を本当に実行する必要がない限りどういうわけか。オブジェクトの純粋主義者を困らせるかもしれませんが、特にこの種のバッチジョブのシナリオでは、ストアドプロシージャが正しい方法であることがあります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top