我有以下数据库结构(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的报告。
ReportA
、ReportB
、ReportC
表中的列不同。
每个 Report
表都有大约 40 000 行。
Company
和 Location
表有大约 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.CompanyId
、ReportA.LocationId
、ReportB.LocationId
、ReportC.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/