Linq to Entities:Count非常缓慢

3

我需要在查询中使用parent和parent.child.count(),但这样做需要20秒的时间...数据库不算很大...有什么优化的想法吗?

var plist = context.persons
  .Select(p => new
  {
    p.fullName,
    c.personID,
    p.Status,
    p.Birthdate,
    p.Accounts.Count
  }).ToList();

4
如果您提供一些代码,我们可能会更好地帮助您。很可能是您的查询评估太早了,实际上正在使用LINQ to Objects进行Count()操作。 - StriplingWarrior
以下是查询代码.....var plist = context.persons.Select(p => new {p.fullName, c.personID, p.Status,p.Birthdate, p.Accounts.Count}).ToList(); - rakeshvenkata
人和账户是实体。Personid 是 Account 表中的外键。一个人可以有零个或多个账户。我需要知道它们的数量... - rakeshvenkata
只是出于好奇,persons和accounts表中有多少条目? - StriplingWarrior
记录数量为590000。 - rakeshvenkata
显示剩余2条评论
6个回答

3

2

嗨,约翰。我是Rakesh。谢谢你的文章。我需要使用Count函数来计算每个父记录的子记录数量,并在网格中显示。我也看到了Craig的这篇文章。 - rakeshvenkata

2

由于这是实体框架,打开SQL Profiler并查看发送到数据库的SQL查询。听起来你可能会发现一个单独的查询被发送来获取组标识符,然后另一组查询(每个组一个)可能在获取计数。如果是这样的话,你需要发布LINQ查询以便其他人解决问题。


以下是查询语句.....var plist = context.persons.Select(p => new {p.fullName, c.personID, p.Status,p.Birthdate, p.Accounts.Count}).ToList(); - rakeshvenkata
人和账户是实体。Personid 是 Account 表中的外键。一个人可以有一个或多个账户。我需要知道数量... - rakeshvenkata
你看过生成的 SQL 吗? - Amy B
记录数量为590000。 - rakeshvenkata

2
根据您发送的代码,看起来事情不应该花费那么长时间。我有几个建议:
  1. 使用LinqPad进行此查询。它将让您查看生成的SQL。然后在SQL Server Management Studio中运行该SQL代码,并告诉它包括实际执行计划。这将帮助您了解查询中是否有特定的点需要花费很多时间。例如,如果您没有在Account表的PersonId引用上创建索引,则此查询将花费更长时间。
  2. 查看您如何使用此数据。非常罕见的是,您真正需要同时将整个系统中的所有人员保存在内存中。实际上,我怀疑仅从数据库中获取所有这些人员数据可能比Count()花费更多的时间。
    • 您是否显示此数据?如果是,只显示十条记录可能会更好,您可以在调用ToList()之前使用.Take(int)方法获取所需数量的记录。
    • 如果您正在处理和聚合此数据以获得站点指标,最好设置查询以返回最终结果,然后再对其进行评估。
如果您可以描述此数据的使用方式,或提供SQL的执行截图,我们可以提供更多反馈。

1

我使用GroupBy方法解决了一个类似的问题。

IEnumerable> accounts = Accounts.GroupBy(x => x.personID); accounts.Count()将返回属于该人的帐户数量。 accounts.Key将返回组的personID。


1

我曾经遇到一个类似的问题,我尝试了以下方法,效果更好:

child.count(x=> x.paretnID == inputParentID) child.where(x=> x.parentID == inputParentID)

我的原始代码在每次迭代中需要花费约15-20秒的时间: return (isEdit) ? db.ChasisBuys.Single(x => x.ChasisBuyID == long.Parse(Request.QueryString["chbid"])).Chasises.Count(y => y.Bikes.Count > 0 && y.ColorID == buyItems[(int)index].ColorID && y.ChasisTypeID == buyItems[(int)index].ChasisTypeID).ToString() : "-";

新的代码运行良好:

        **return (isEdit) ? db.Chasises.Where(x => x.ChasisBuyID == long.Parse(Request.QueryString["chbid"])).Count(y => y.Bikes.Count > 0 && y.ColorID == buyItems[(int)index].ColorID && y.ChasisTypeID == buyItems[(int)index].ChasisTypeID).ToString() : "-";**

数据库中有大约1000个底盘记录,大约有5个底盘购买记录和20个自行车记录。我的观点是,Linq to SQL查询不会像逻辑语句那样进行先前评估,例如如果您写“return a && b && c;”,如果语句a为false,则不评估其他语句,我期望Linq to SQL也能这样做,但实际并非如此。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接