c# - EF 加入 5 个大表 - Include() 方法优化

标签 c# sql-server database performance entity-framework

我有以下数据库结构(EDMX 模型):

public class Company 
{
    public Guid Id { get; set; }
    public virtual ICollection<Location> Locations { get; set; }
    // ... 15 more columns
}

public class Location 
{ 
    public Guid Id { get; set; }
    public virtual Company Company { get; set; }
    public Guid CompanyId { get; set; }

    public virtual ICollection<ReportA> ReportsA { get; set; }
    public virtual ICollection<ReportB> ReportsB { get; set; }
    public virtual ICollection<ReportC> ReportsC { get; set; }
    // ... 15 more columns with information - name, description etc.
}

public class ReportA
{
    public virtual Location Location { get; set; }
    public Guid LocationId { get; set; }
    // 30 more columns of type "int?"
}

public class ReportB
{
    public virtual Location Location { get; set; }
    public Guid LocationId { get; set; }
    // 30 more columns of type "int?"
}

public class ReportC
{
    public virtual Location Location { get; set; }
    public Guid LocationId { get; set; }
    // 30 more columns of type "int?"
}

一个公司可以有多个地点。每个地点都有很多来自A、B、C的报告。
ReportAReportBReportC 表中的列不同。
每个 Report 表都有大约 40 000 行。
CompanyLocation 表有大约 5000 行

我需要获取所有数据并做一个总结报告。
代码是:

 using (ComapnyEntities dataBaseContext = new ComapnyEntities())
 {
      IQueryable<Locations> query = dataBaseContext.Locations
            .AsNoTracking()
            .Where(location => companyIds.Contains(location.CompanyId))
            .Include(location => location.Company)
            .Include(location => location.ReportsA)
            .Include(location => location.ReportsB)
            .Include(location => location.ReportsC);
       // more filtation 
       return query.ToList();

       // assume that companyIds have all company Ids 
}

在大多数情况下,我可以使用 Skip()Take() 方法来加快执行速度(即 .Take(10)) ,但在一种特殊情况下,我需要提取所有位置以及公司信息 ReportsA、ReportsB、ReportsC。

根据 Stackoverflow 中的评论,Include() 按行生成笛卡尔积。 https://stackoverflow.com/a/22625208/6142097

 // so if that is true:
 4 000 * 4 000 * 40 000 * 40 000 * 40 000 = ?? (1.024e+21)

“好的部分”是页面需要 15 秒来加载(本地),但在生产环境中并不相同并且需要更长的时间。

那么有没有办法提高查询的性能呢?

  • 我试过 Entity-framework code is slow when using Include() many times - 比较慢
  • 我添加了 Location.CompanyIdReportA.LocationIdReportB.LocationIdReportC.LocationId 的非聚集索引, LocationId - 没有区别(我不确定索引是否正确添加)
  • 无法构建连接所有表的原生 SQL 查询,执行时间不到 10 秒。
  • 我尝试用 .IncludeOptimized() 替换 .Inlude() 但没有真正的区别。

我的机器使用 SQL Server 2014 和 windows 8.1

你有什么建议?有没有办法改进我的代码?

最佳答案

I need to get all of the data and make a summary report.

你不应该“得到所有的数据”来“做一个总结报告”。而是编写返回摘要的查询,而不是每一行。

关于c# - EF 加入 5 个大表 - Include() 方法优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44227864/

相关文章:

c# - 避免在 C# 中使用 goto 语句

mysql - 从 MS SQL 迁移到 MySQL : SQLOLEDB? 迁移套件登录错误?

java - 在 Web 应用程序中管理数据库连接的最佳实践

mysql - 在数据库中存储 100K 个不同的表

c# - 如何从 C# 访问 C++/CLI 中的类?

c# - 从 UWP 手机应用更新现有的 Microsoft Band Tile

sql-server - 全文搜索中的 CONTAINS 不会返回所有结果

php - Symfony 4.2 无法连接到 Microsoft SQL Server

mysql - 将 cte 转换为 mysql

c# - (x, y).GetHashCode() 如何在幕后工作?