Gur*_*ruC 4 c# mysql ado.net entity-framework
我正在使用一个ADO .Net Entity Model
查询MySQL数据库.我对它的实现和使用感到非常高兴.我决定看看如果我查询了100万条记录会发生什么,并且它有严重的性能问题,我不明白为什么.
系统挂起一段时间,然后我得到
我的代码如下::
try
{
// works very fast
var data = from employees in dataContext.employee_table
.Include("employee_type")
.Include("employee_status")
orderby employees.EMPLOYEE_ID descending
select employees;
// This hangs the system and causes some deadlock exception
IList<employee_table> result = data.ToList<employee_table>();
return result;
}
catch (Exception ex)
{
throw new MyException("Error in fetching all employees", ex);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么ToList()花了这么长时间?
另外,如何避免此异常以及查询百万条记录的理想方式是什么?
msa*_*het 12
查询一百万条记录的理想方法是使用a IQueryable<T>
来确保在您需要实际数据之前实际上没有在数据库上执行查询.我非常怀疑你一次需要一百万条记录.
它是死锁的原因是你要求MySQL服务器从数据库中提取那些百万条记录,然后按顺序排序EMPLOYEE_ID
,然后让你的程序将它返回给你.所以我想象死锁是来自你的程序等待它完成,以及你的程序将其读入内存.MySQL问题可能与超时问题有关.
该var data
部分快速工作的原因是因为你实际上还没有做任何事情,你刚刚构建了查询.当你调用时,ToList()
所有SQL和SQL的读取都被执行.这就是所谓的Lazy Loading.
我建议尝试如下:
var data = from employees in dataContext.employee_table
.Include("employee_type")
.Include("employee_status")
orderby employees.EMPLOYEE_ID descending
select employees;
Run Code Online (Sandbox Code Playgroud)
然后,当你真正需要列表中的东西时,只需要调用
data.Where(/* your filter expression */).ToList()
Run Code Online (Sandbox Code Playgroud)
因此,如果您需要ID为10的员工.
var employee = data.Where(e => e.ID == 10).ToList();
Run Code Online (Sandbox Code Playgroud)
或者,如果您需要姓氏以S开头的所有员工(我不知道您的表是否有姓氏列,只是一个例子).
var employees = data.Where(e => e.LastName.StartsWith("s")).ToList();
Run Code Online (Sandbox Code Playgroud)
或者,如果您想以100块的方式浏览所有员工
var employees = data.Skip(page * 100).Take(100).ToList();
Run Code Online (Sandbox Code Playgroud)
如果您想进一步推迟数据库调用,则无法调用ToList()
并在需要时使用迭代器.因此,假设您想要将名称以A开头的人的所有工资加起来
var salaries = data.Where(s => s.LastName.StartsWith("A"))
foreach(var employee in salaries)
{
salaryTotal += employee.Salary;
}
Run Code Online (Sandbox Code Playgroud)
这只会做一个类似的查询
Select Salary From EmployeeTable Where ID = @ID
Run Code Online (Sandbox Code Playgroud)
导致一个非常快速的查询,只在您需要时获取信息,并且只获取您需要的信息.
如果出于某些疯狂的原因,您想要实际查询数据库的所有百万条记录.忽略这会占用大量系统资源这一事实我建议以块的形式进行,你可能需要使用块大小来获得最佳性能.
一般的想法是进行较小的查询以避免数据库出现超时问题.
int ChunkSize = 100; //for example purposes
HashSet<Employee> Employees - new HashSet<Employee>;
//Assuming it's exactly 1 Million records
int RecordsToGet = 1000000;
for(record = 0; record <= RecordsToGet; record += ChunkSize)
{
dataContext.EmployeeTable.Skip(record).Take(ChunkSize).ForEach(e => HashSet.Add(e));
}
Run Code Online (Sandbox Code Playgroud)
我选择使用a,HashSet<T>
因为它们是为大型数据集而设计的,但我不知道哪些性能看起来像1,000,000个对象.
归档时间: |
|
查看次数: |
4124 次 |
最近记录: |