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 天前创建的 Classeses 包含在计数中

编辑

我有一个名为 People 的表,在此查询中称为 P 并且我想返回没有所有者的 Pets 总数,并从查询中删除没有所有者的 Pets有一个所有者,即使它们存在于另一个 Pet 引用中也没有该 Pet 的所有者。这意味着如果一个人在 Pets 表中至少有一条记录被视为宠物的所有者,那么我想删除该人存在于返回查询中的所有情况,一旦完成,只返回已创建的 Pets超过 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

您可以使用(并且可能首先创建)导航属性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涉及不可预测数量的字符串的两阶段查询具有更好的可扩展性。

当然,您还需要确保CreatedDate.

于 2013-08-03T20:43:18.830 回答
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 回答