2

正しい結果が得られるこのクエリがありますが、実行に約 15 秒かかります

int Count= P.Pets.Where(c => !P.Pets.Where(a => a.IsOwned == true)
.Select(a => a.OwnerName).Contains(c.OwnerName) && c.CreatedDate >= 
EntityFunctions.AddDays(DateTime.Now, -8)).GroupBy(b=>b.OwnerName).Count();

linq のこの部分を削除すると

 '&& c.CreatedDate >= EntityFunctions.AddHours(DateTime.Now, -8)'

実行にかかる時間はわずか 3 秒です。どうすれば同じ状態を維持できますが、はるかに高速になりますか? 8 日前に作成されたクラスをカウントに含めたくないので、その日付基準が必要です

編集

このクエリで P と呼ばれる People という名前のテーブルがあり、所有者を持たないペットの総数を返し、そうでないものをクエリから削除したいそれらが別のペット参照に存在する場合でも所有者を持ち、そのペットの所有者を持っていません。Pets テーブルにペットの所有者と見なされるレコードが少なくとも 1 つある場合、その人が返されるクエリに存在するすべてのケースを削除し、それが完了すると、作成されたペットのみを返すことを意味します。 8 日より新しい

4

4 に答える 4

2

日付をキャッシュし、その評価を最初に配置するDateTime必要があります (評価は評価よりも高速であるためContains)。また、同じクエリを複数回再計算することも避けてください。

DateTime eightDaysOld = EntityFunctions.AddHours(DateTime.Now, -8);

//calculate these independently from the rest of the query
var ownedPetOwnerNames = P.Pets.Where(a => a.IsOwned == true)
                               .Select(a => a.OwnerName);

                              //Evaluate the dates first, it should be 
                              //faster than Contains()
int Count = P.Pets.Where(c => c.CreatedDate >= eightDaysOld &&

                              //Using the cached result should speed this up
                              ownedPetOwnerNames.Contains(c.OwnerName))
                  .GroupBy(b=>b.OwnerName).Count();

それは同じ結果を返すはずです。(私は願います)

于 2013-08-02T20:32:25.090 に答える
0

すべての行の静的な日付を計算するため、そのスニペットでインデックスを使用する機能が失われています。DateTimeクエリの前に変数を宣言し、それをに設定しDateTime.Now.AddHours(-8)て、where 句でスニペットの代わりに変数を使用します。

于 2013-08-02T19:09:35.500 に答える
0

クエリを分離して ToList() を呼び出し、それをマスター クエリに挿入すると、4 倍速くなります

 var ownedPetOwnerNames = P.Pets.Where(a => a.IsOwned == true)
                           .Select(a => a.OwnerName).ToList();


int Count = P.Pets.Where(c => c.CreatedDate >= Date&&

  ownedPetOwnerNames.Contains(c.OwnerName)).GroupBy(b=>b.OwnerName).Count();
于 2013-08-02T21:22:36.310 に答える
0

ナビゲーション プロパティを使用する (そして最初に作成する) ことができますPet.Owner

var refDate = DateTime.Today.AddDays(-8);

int Count= P.Pets
            .Where(p => !p.Owner.Pets.Any(p1 => p1.IsOwned)
                        && p.CreatedDate >= refDate)
            .GroupBy(b => b.OwnerName).Count();

Containsがなくなるため、これによりパフォーマンスが向上する可能性があります。Contains少なくとも、予測できない数の文字列を含む2 フェーズ クエリよりもスケーラブルです。

もちろん、 にインデックスがあることも確認する必要がありますCreatedDate

于 2013-08-03T20:43:18.830 に答える