私はこれについての専門家ではないので、DB4O フォーラムに投稿するのは良いことかもしれませんが、私には解決策があると思います。LINQ を使用せず、SODA を使用する必要があります。
これが私がしたことです。投稿の定義に基づいて、データベースに 30000 個の SimpleObject を入力する簡単なプロジェクトを作成しました。次に、データベースからすべての SimpleObjects を取得するクエリを作成しました。
var simpleObjects = db.Query<SimpleObject>(typeof(SimpleObject));
ストップウォッチをラップすると、その実行には約 740 ミリ秒かかります。次に、コードを使用して、0 から 2999 までの 100 個の乱数を検索しました。応答は 772 ミリ秒だったので、その数値に基づいて、データベースからすべてのオブジェクトを引き出していると想定しています。それを確認する方法はわかりませんが、後でパフォーマンスで証明したと思います。
それから私は下に行きました。私の理解では、DB4O チームの LINQ プロバイダーは SODA への変換を行っているだけです。したがって、テストのために SODA クエリを作成することにしました。実行に 19902 ミリ秒かかるため、プロパティに対して SODA を使用するとパフォーマンスが低下することがわかりました。コードは次のとおりです。
private SimpleObject[] GetSimpleObjectUsingSodaAgainstAProperty(int[] matchingIds, IObjectContainer db)
{
SimpleObject[] returnValue = new SimpleObject[matchingIds.Length];
for (int counter = 0; counter < matchingIds.Length; counter++)
{
var query = db.Query();
query.Constrain(typeof(SimpleObject));
query.Descend("Id").Constrain(matchingIds[counter]);
IObjectSet queryResult = query.Execute();
if (queryResult.Count == 1)
returnValue[counter] = (SimpleObject)queryResult[0];
}
return returnValue;
}
なぜこれが悪いのかを考えて、プロパティは実際には値ではなくメソッドであるため、自動実装されたプロパティを使用せずに自分で定義することにしました。
public class SimpleObject
{
private int _id;
public int Id {
get
{ return _id; }
set
{ _id = value; }
}
}
次に、プロパティの代わりに _id プライベート フィールドを使用するようにクエリを書き直しました。パフォーマンスは約 91 ミリ秒ではるかに優れていました。そのコードは次のとおりです。
private SimpleObject[] GetSimpleObjectUsingSodaAgainstAField(int[] matchingIds, IObjectContainer db)
{
SimpleObject[] returnValue = new SimpleObject[matchingIds.Length];
for (int counter = 0; counter < matchingIds.Length; counter++)
{
var query = db.Query();
query.Constrain(typeof(SimpleObject));
query.Descend("_id").Constrain(matchingIds[counter]);
IObjectSet queryResult = query.Execute();
if (queryResult.Count == 1)
returnValue[counter] = (SimpleObject)queryResult[0];
}
return returnValue;
}
まぐれではないことを確認するために、テストを数回実行しましたが、同様の結果が得られました。次に、さらに 60,000 レコードを追加して合計 90,000 にしたところ、パフォーマンスの違いは次のようになりました。
GetAll: 2450 ms
GetWithOriginalCode: 2694 ms
GetWithSODAandProperty: 75373 ms
GetWithSODAandField: 77 ms
それが役立つことを願っています。理由を実際に説明していないことはわかっていますが、これはその方法に役立つかもしれません。また、SODA フィールド クエリのコードをより汎用的にラップすることも難しくありません。