ac# プロジェクトの SQLite DB で NHibernate を使用しています。次のような一般的な一括データ処理メソッドがあります。
private void DataProcess<Tobj>(int pageSize, Expression<Func<Tobj, bool>> whereClause,
Action<Tobj, ISession> dataProcessingCallback) where Tobj : IModelBase
{
int offset = 0;
bool moreToGet = true;
while (moreToGet)
{
DataAccess((ISession session) =>
{
IEnumerable<Tobj> result = session.Query<Tobj>().Where(whereClause);
List<Tobj> data = result.Skip(offset)
.Take(pageSize)
.ToList();
foreach (Tobj item in data) { dataProcessingCallback(item, session); }
if (data.Count == pageSize) { offset += pageSize; }
else { moreToGet = false; }
});
}
}
(DataAccess メソッドは、操作するセッション オブジェクトを提供し、トランザクションを処理します。)
周りを見渡すと、これは他のほとんどの linq ページング実装と非常によく似ているようです。彼らは一般的に .Skip().Take() を行います
私の問題は、大規模なデータ セット (私が見ているテスト ケースでは約 20 万行あります) の場合、result.Skip(offset).Take(pageSize).ToList を実行するのに AGES (デバッガーで約 20 秒) かかることです。 (); ライン。これは pageSize = 100 で、offset = 0 です。
私の理解では、遅延実行のため、必要になるまで SELECT は発生しません (この場合は .ToList())。この時点で、必要な行は関連する 100 行のみを選択する必要があることがわかります。
「データ」には予想される 100 行がありますが、システムが DB から 200k の奇数行をすべてフェッチし、コードでページングを実行したように見えます。
私のLINQ/NHibernateの理解は間違っていますか? もしそうなら、基準 API で次のようなことをする必要があると思います: NHibernate Paging performance (Better option)