0

テーブルでエントリを検索するときにパフォーマンスの問題があるとします。例に行きましょう:

public class A {

[Key]
public int Id {get;set;}

public string xyz {get; set;}

}

public class Context : DbContext {

public DbSet<A> AList {get;set;}

public A FindA(string xyz) {

A output = null;

   if(AList.Local != null) {
     output = AList.Local.SingleOrDefault(x=>x.xyz==xyz);
   }

   return output ?? AList.SingleOrDefault(x=>x.xyz==xyz);

}

}

メソッド FindA は最初に Local コレクションを検索し、一致するものがない場合はデータベースに移動します。要素の重複挿入を避けるために、このアプローチが必要です。

このアプローチの問題は単純です: AList.Local の検索は O(n) の複雑さを持ち、私の場合、AList.Local はしばしば 100,000 レコードを超えます。AList.Local が xyz プロパティでインデックス付けされたディクショナリであるとしたら、それは素晴らしいことです。ただし、EF Code First の IDbSet は、まったくインデックス付けされていない ObservableCollection を使用します。

考えられる解決策の 1 つは、Dictionary を AList.Local のミラーとして維持することです。ただし、AList.Local への変更を追跡するのは簡単ではないため、これは注意が必要です。

別の解決策は、xyz プロパティを主キーにして AList.Find(xyz) メソッドを使用することです (エンティティがローカル キャッシュにある場合でも、O(1) 検索であることを願っています)。ただし、主キーとして文字列を使用すると、データベースのパフォーマンスに影響を与え、インデックス ファイルのサイズが大幅に増加すると思われます。

この状況を克服する方法について誰か提案してもらえますか?

4

1 に答える 1

0

Entity Framework の高パフォーマンスが懸念される場合は、変更の追跡を無効にする必要があり、LINQ または LINQ メソッドの構文は使用しないでください。変更の追跡は大きなトラブルメーカーであり、LINQ の代わりに従来のループを使用すると2 倍速くなりますが、LINQ よりも従来のループを優先する場合、1 回のルックアップ操作で数ミリ秒しか削ることができません。

于 2013-01-05T20:38:07.413 に答える