我正在尝试从数据库中获取记录。
我的数据库表:
上表包含大量记录。
我的数据将根据以下结构生成:
我尝试了什么:
我的第一个方法:
//Get all the departments
List<Department> departmentList = sp.GetAllDeparments();
//Get all employees
List<Employee> employeeList= sp.GetAllEmployees();
//Get all locations
List<Location> locationList= sp.GetAllLocations();
//Get EmployeeLocations List<EmployeeLocations> emplocationList=
sp.GetAllEmployeeLocations();
//Get EmployeeDepartments List<EmployeeDepartments> empDepList=
sp.GetAllEmployeeDepartments();
foreach(Deparment deparment in departmentList){
foreach(Employee employee in employeeList){
foreach(Location location in locationList){
}
}
}
如果我在foreach循环中点击数据库,上面的代码大约需要6分钟。
我的第二种方法:
{{1}}
我从所有上述表中获取所有记录,并在foreach代码中使用LINQ进行操作。因此,将时间从6分钟缩短到4分钟。
我的问题: 在尽可能短的时间内获取数据的有效方法是什么。在这种情况下?
我需要在上图中操作数据。
答案 0 :(得分:1)
涉及较少数据库往返的第二种方法要好得多。但根据你的评论
即使我目前正在使用第二种方法,一次获取数据并将其保存在内存中也不是问题。但是在做foreach时我正在使用LambdaExpression进行提取。这需要时间。
看起来您的处理部分正在使用大量低效的线性搜索。通过准备和使用基于快速哈希的查找数据结构,可以显着改善它。
在这种特殊情况下,您需要两个dictionaries来快速定位员工PK和PK定位,两个lookups用于按部门PK快速定位员工,按员工PK定位员工。
假设您的类模型是这样的(您可以使用实际的属性名称/类型对其进行修改):
class Department
{
public int Id { get; set; } // PK
// Other properties...
}
class Employee
{
public int Id { get; set; } // PK
// Other properties...
}
class Location
{
public int Id { get; set; } // PK
// Other properties...
}
class EmployeeDepartment
{
public int EmployeeId { get; set; } // FK
public int DepartmentId { get; set; } // FK
}
class EmployeeLocation
{
public int EmployeeId { get; set; } // FK
public int LocationId { get; set; } // FK
}
然后处理可能是这样的:
//Fetch all necessary data
List<Department> departmentList = sp.GetAllDeparments();
List<Employee> employeeList = sp.GetAllEmployees();
List<Location> locationList = sp.GetAllLocations();
List<EmployeeLocation> employeeLocationList = sp.GetAllEmployeeLocations();
List<EmployeeDepartment> employeeDepartmentList = sp.GetAllEmployeeDepartments();
// Build the helper fast lookup structures
var employeeById = employeeList.ToDictionary(e => e.Id);
var locationById = locationList.ToDictionary(e => e.Id);
var employeesByDepartmentId = employeeDepartmentList.ToLookup(e => e.DepartmentId, e => employeeById[e.EmployeeId]);
var locationsByEmployeeId = employeeLocationList.ToLookup(e => e.EmployeeId, e => locationById[e.LocationId]);
// The processing
foreach (Department deparment in departmentList)
{
foreach (Employee employee in employeesByDepartmentId[deparment.Id])
{
foreach (Location location in locationsByEmployeeId[employee.Id])
{
}
}
}
答案 1 :(得分:0)
问题&amp;建议; 强>
如果在接收数据时重复打开sql连接 从列表中,只需要一个数据库请求。你需要 列出该请求中多次出现的列表
结果:请求应该发送到数据库一次。我摔倒 使用字典方法检索列表,然后15% 实现了性能提升。如果你的工作真的很大 数据,你可以异步工作
如果需要更多细节,我们需要查看以get开头的函数的内容。