优化EntityFramework查询

时间:2015-08-03 13:47:18

标签: c# linq entity-framework

我有两张桌子 - ReferrerSources,大小为50行,Referrer,大小为150万行。

每个Refferer实体都有指向相应ReferrerSource的链接。 我只需计算每个Referrer的{​​{1}}个数:

ReferrerSource

但是这段代码在执行30秒后会导致public void CreateConvertionReportTest(DateTime from, DateTime to) { //.GetAll() returns IQueryable<T>. It's equal to Context.Set<T>(). var src = ContextManager.ReferrerSourceContext.GetAll(); var reff = ContextManager.ReferrerContext .GetAll() .Where(r => r.Created >= from && r.Created < to); var info = src.GroupJoin( reff, (s) => s.Id, (r) => r.ReferrerSourceId, (s, or) => new { sorce = s.Name, refferrersCount = or.Count() } ); foreach(var g in info) Console.WriteLine("src: " + g + " : " + g.refferrersCount); }

我知道,那个简单的SQL脚本可以在一瞬间完成。我做错了什么?

2 个答案:

答案 0 :(得分:1)

你只需要投影来解决这个问题,我没有你的代码所以这是我自己使用我自己的存储库的一个例子,但EF部分幸存下来因为我使用了iquerable:

var companyList = _companyRepo
            .Query()
            .Select(c => new
            {
                label = c.Name,
                count = c.Projects.Count
            }).ToList();

我认为/希望您能够将其转化为您的需求。 因此,根据我对您的问题的理解,这将返回公司列表和每个公司拥有的项目数量。在我的数据模型中,公司可以拥有许多项目,因此公司和项目之间存在导航属性。 如果您使用导航属性,则无需连接。

检查数据库中的Referer表上的索引。对于引用来源的外键应该有一个索引。

您可以使用sql server profiler来检查执行的查询。手动在分析器中执行这些查询,让它们进行优化。它也会建议丢失索引。但我感觉上面提到的索引缺失了。

答案 1 :(得分:0)

如果您正确设置了导航属性,并且我了解您的模型,您应该可以这样做:

var src = ContextManager.ReferrerSourceContext.GetAll()
    Select(x => new 
    {
        Source = x.Name,
        RefferersCount = x.Refferers
            .Where(r => r.Created >= from && r.Created < to)
            .Count()
    });

foreach(var source in src)
{
    Console.WriteLine("src: " + source.Name + " : " + RefferersCount);
}