简体   繁体   English

Linq to Entities:伯爵很慢

[英]Linq to Entities : Count is very slow

I need to have parent and parent.child.count()....in the query.. when i do this it is taking 20 seconds....its not a huge database...Any ideas for optimization... 我需要在查询中使用parent和parent.child.count()....当我这样做时需要20秒....它不是一个庞大的数据库...任何优化的想法......

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

Here is a great article on using count() when you really meant to use any() 这篇文章是关于在你真正想要使用any()时使用count()的好文章

http://blogs.teamb.com/craigstuntz/2010/04/21/38598/ http://blogs.teamb.com/craigstuntz/2010/04/21/38598/

Do you need to use .count or could you use .any? 你需要使用.count还是可以使用.any?

http://msdn.microsoft.com/en-us/library/bb534972.aspx http://msdn.microsoft.com/en-us/library/bb534972.aspx

Since this is entity framework, open up the sql profiler and take a look at what sql queries are being sent to the database. 由于这是实体框架,请打开sql profiler并查看正在向数据库发送的SQL查询。 It sounds like you may see that a single query is sent to fetch the group identifiers, and then another set of queries (one for each group) might be fetching the count. 听起来您可能会看到发送单个查询以获取组标识符,然后另一组查询(每个组一个)可能正在获取计数。 If that's happening, you'll have to post the linq query for someone to resolve the issue. 如果发生这种情况,您必须发布linq查询给某人以解决问题。

Based on the code you sent, it doesn't look like things should be taking that long. 根据您发送的代码,看起来事情应该花费那么长时间。 I have a few suggestions: 我有一些建议:

  1. Use LinqPad to do this query. 使用LinqPad执行此查询。 It will let you see the SQL that gets generated. 它将让您看到生成的SQL。 Then run that SQL code in SQL Server Management Studio, and tell it to include the actual execution plan. 然后在SQL Server Management Studio中运行该SQL代码,并告诉它包含实际的执行计划。 This will help you learn whether there's a particular point in the query that's taking a lot of time. 这将帮助您了解查询中是否存在花费大量时间的特定点。 For example, if you don't have an index on the Account table's PersonId reference, this query will take a lot longer. 例如,如果您在Account表的PersonId引用上没有索引,则此查询将花费更长的时间。
  2. Look at how you're using this data. 看看你如何使用这些数据。 It's very rare that you really need to have all the people in your entire system in memory at the same time. 您真的需要同时将整个系统中的所有人都放在内存中,这是非常罕见的。 In fact, I suspect that simply getting all this person data out of the database is probably taking a lot more time than the Count() is. 事实上,我怀疑只是将所有这些人员数据从数据库中取出可能比Count()花费的时间多得多。
    • Are you displaying this data? 你在显示这些数据吗? If so, wouldn't it be better to "page" the results, only showing maybe ten entries at a time? 如果是这样,那么“页面”结果不是更好,一次只能显示十个条目吗? You can use the .Take(int) method before calling .ToList() to get only as many entries as you need. 您可以在调用.ToList()之前使用.ToList() .Take(int)方法,以获得所需数量的条目。
    • If you're processing and aggregating this data for the sake of site metrics, it's probably better to set up your query to return the end result before it gets evaluated. 如果您为了站点指标而处理和聚合此数据,则最好设置查询以在评估之前返回最终结果。

If you can describe how this data is being used, or provide a screenshot of the SQL's execution, we can provide more feedback. 如果您可以描述如何使用此数据,或提供SQL执行的屏幕截图,我们可以提供更多反馈。

I had a somehow similar problem, I tried these and worked out better : 我有一个类似的问题,我尝试了这些并且更好地解决了:

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

my original code which took around 15-20 seconds on each iteration was: return (isEdit) ? 我的原始代码在每次迭代时花了大约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() : "-"; 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():“ - ”;

new code which runs good is : 运行良好的新代码是:

        **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() : "-";**

Database has around 1000 records in chasises , about 5 in chasisBuys and about 20 in Bikes. 数据库在chasises中有大约1000条记录,在chasisBuys中大约有5条记录,在自行车中大约有20条。 my opinion is that Linq to SQL queries does not do preevaluations such in logical statements which for instance if you write "return a && b && c;" 我的观点是Linq to SQL查询不会在逻辑语句中进行预先评估,例如,如果你写“return a && b && c;” if statement a is false other statements are not evaluated and I was expecting such thing in linq to sql but it's not the case. 如果语句a是false,则其他语句不会被评估,我在linq中期待这样的事情,但事实并非如此。

I solved a similar problem using the GroupBy method. 我使用GroupBy方法解决了类似的问题。

IEnumerable> accounts = Accounts.GroupBy(x => x.personID); IEnumerable> accounts = Accounts.GroupBy(x => x.personID); accounts.Count() will return the number of accounts that belong to the person. accounts.Count()将返回属于该人的帐户数。 accounts.Key will return the personID of the group. accounts.Key将返回组的personID。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM