C# LINQ中的列表搜索性能较慢
我有一张表,每个月都有超过200000条记录 从表中获取记录并不是一个问题,它可以按预期工作,但搜索记录的性能非常慢C# LINQ中的列表搜索性能较慢,c#,.net,asp.net-mvc,performance,linq,C#,.net,Asp.net Mvc,Performance,Linq,我有一张表,每个月都有超过200000条记录 从表中获取记录并不是一个问题,它可以按预期工作,但搜索记录的性能非常慢 var listEmpShiftDetails =ctx.tblTO_ShiftSchedule .Where(m => m.CompanyId == companyId && m.ShiftDate >= fromd
var listEmpShiftDetails =ctx.tblTO_ShiftSchedule
.Where(m => m.CompanyId == companyId &&
m.ShiftDate >= fromdate &&
m.ShiftDate <= todate)
.Select(m => m).ToList();
上面两行的执行时间太长,下面是VisualStudio的输出。如何提高性能
分析器输出
var listEmpShiftDetails=从数据库中获取的记录大约:-20万条记录
foreach (var item in data) // Data consist of employee details 3k Records
{
var selectedItem = listEmpShiftDetails.FirstOrDefault(m => m.EmployeeId == item.Id &&
m.ShiftDate == item.Entry_Date);
if (selectedItem != null)
{
// Other Calculations
}
}
不需要多次迭代同一查询。您只需要第一个匹配项,否则为null。希望上面的查询能给您带来更好的性能。首先,这样做可以避免执行两次查询:
foreach (var item in data) // Data consist of employee details 3k Records
{
var shiftDetails = listEmpShiftDetails.Where(m => m.EmployeeId == item.Id && m.ShiftDate == item.Entry_Date).FirstOrDefault()
if (shiftDetails != null)
{
//Other Calculations
}
}
接下来,您似乎正在进行某种形式的连接,最好看看数据的组成部分,这样我们就可以进一步提出一种方法来显著缩短时间
这可能会给您带来一些改进:
var query =
(
from a in ctx.tblEmployee.Where(x => x.CompanyId == companyId)
join b in ctx.tblTO_Entry.Where(x => x.CompanyId == companyId) on a.Id equals b.EmployeeId
where b.Entry_Date >= fromDate
where b.Entry_Date <= toDate
join m in ctx.tblTO_ShiftSchedule.Where(x => x.CompanyId == companyId) on new
{
a.Id,
b.Entry_Date
} equals new
{
Id = m.EmployeeId,
Entry_Date = m.ShiftDate
} into g
from m2 in g.Where(x => x.ShiftDate >= fromDate).Where(x => x.ShiftDate <= toDate).Take(1)
select m2
).ToList();
foreach (var shiftDetails in query)
{
//Other Calculations
}
var查询=
(
从ctx.tblEmployee.Where(x=>x.CompanyId==CompanyId)中的
在ctx.tblTO_条目中加入b,其中a.Id上的(x=>x.CompanyId==CompanyId)等于b.EmployeeId
其中b.Entry\u Date>=fromDate
其中,b.Entry_Date x.CompanyId==CompanyId)在新的
{
a、 身份证,
b、 入境日期
}等于新的
{
Id=m.EmployeeId,
输入日期=m.ShiftDate
}进入g
从g.Where中的m2(x=>x.ShiftDate>=fromDate)。Where(x=>x.ShiftDate查看您的查询后,我的头上出现了什么:
额外的查询加载,无需检查If(){}
如果您的“listEmpShiftDetails”是可查询的,则listEmpShiftDetails.Any()是可以的。但如果是列表,则会妨碍性能。
保持你的查询简单
var shiftDetails = listEmpShiftDetails.FirstOrDefault(m => m.EmployeeId == item.Id && m.ShiftDate == item.Entry_Date);
同一个查询执行了两次。只需执行一次。“20万条记录”?200000条记录您是否需要第一行?只需检查第二行返回任何内容的结果。@Nilesh-您应该向我们展示您的完整代码。我们应该了解如何从数据库中检索所有数据以及您是如何准备的。然后我们可以给您一个正确的答案。更新上述代码后,还需要4-5分钟的时间从op复制过去,但复制到最右边以引起注意。或者它是一个遗留,因为op执行select但未显示其详细信息。但如果不需要select,则应将其删除,因为select将需要where select枚举迭代器的其他实例。性能增益很小。
var query =
(
from a in ctx.tblEmployee.Where(x => x.CompanyId == companyId)
join b in ctx.tblTO_Entry.Where(x => x.CompanyId == companyId) on a.Id equals b.EmployeeId
where b.Entry_Date >= fromDate
where b.Entry_Date <= toDate
join m in ctx.tblTO_ShiftSchedule.Where(x => x.CompanyId == companyId) on new
{
a.Id,
b.Entry_Date
} equals new
{
Id = m.EmployeeId,
Entry_Date = m.ShiftDate
} into g
from m2 in g.Where(x => x.ShiftDate >= fromDate).Where(x => x.ShiftDate <= toDate).Take(1)
select m2
).ToList();
foreach (var shiftDetails in query)
{
//Other Calculations
}
var shiftDetails = listEmpShiftDetails.FirstOrDefault(m => m.EmployeeId == item.Id && m.ShiftDate == item.Entry_Date);