问题描述
|
(只需说明一下:我的应用与员工和部门无关。我只是出于举例目的使用这些术语)。
每个部门都有一个员工集合,这些集合是延迟加载的。每当我添加新员工时,我都想确保它在集合中尚不存在,因此我将集合加载到内存中并对其进行检查。
问题是-在生产环境中,我有些部门的员工人数超过10,000。
我发现获取集合然后保存新员工需要很多时间。
我做了一些实验,在其中我将nH生成的完全相同的select语句复制到ADO.Net SQLDataAdapter。结果如下:
***16:04:50:437*** DEBUG NHibernate.SQL - SELECT ... FROM dbo.[Employee] emp0_ left outer join dbo.[Department] department1_ on emp0_.Department_id=department1_.Id left outer join dbo.[TableC] TableC2_ on department1_.TableC_id=TableC2_.Id WHERE emp0_.SomeField_id=@p0;@p0 = 2
***16:05:00:250*** DEBUG NHibernate.SQL - SELECT ... FROM dbo.TableD codeshared0_ left outer join dbo.[Department] department1_ on codeshared0_.Department_id=department1_.Id left outer join dbo.[TableC] TableC2_ on department1_.TableC_id=TableC2_.Id WHERE codeshared0_.Employee_id in (select emp0_.Id FROM dbo.[Employee] emp0_ left outer join dbo.[Department] department1_ on emp0_.Department_id=department1_.Id left outer join dbo.[TableC] TableC2_ on department1_.TableC_id=TableC2_.Id WHERE emp0_.SomeField_id=@p0);@p0 = 2
16:05:04:984 DEBUG NHibernate.SQL - Reading high value:select next_hi from dbo._uniqueKey with (updlock,rowlock)
16:05:05:078 DEBUG NHibernate.SQL - Updating high value:update dbo._uniqueKey set next_hi = @p0 where next_hi = @p1;@p0 = 10686,@p1 = 10685
***16:05:05:328*** DEBUG MyApp.Managers - commiting
16:05:12:000 DEBUG NHibernate.SQL - INSERT INTO dbo.[Employee] (...) VALUES (@p0,@p1,@p2,@p3,@p4,@p5,@p6,@p7,@p8,@p9);@p0 = 23/04/2011 04:04:49,@p1 = 23/04/2011 03:34:49,@p2 = 23/04/2011 04:04:49,@p3 = 23/04/2011 03:34:49,@p4 = \'\',@p5 = False,@p6 = 433,@p7 = NULL,@p8 = 2,@p9 = 10685
16:05:12:140 DEBUG NHibernate.SQL - UPDATE dbo.[Employee] SET Department_id = @p0 WHERE Id = @p1;@p0 = 2,@p1 = 10685
16:05:12:343 DEBUG MyApp.Managers - success
16:05:12:359 DEBUG MyApp.Tests - ------------------------------------------------------------
16:05:12:359 DEBUG MyApp.Tests - Finished nHib stuff- now switching to ADO
16:05:12:359 DEBUG MyApp.Tests - starting SQL: SELECT ... FROM dbo.[Employee] emp0_ left outer join dbo.[Department] department1_ on emp0_.Department_id=department1_.Id left outer join dbo.[TableC] TableC2_ on department1_.TableC_id=TableC2_.Id WHERE emp0_.SomeField_id=2
16:05:14:750 DEBUG MyApp.Tests - total rows received: 10036
16:05:14:750 DEBUG MyApp.Tests - SQL: SELECT ... FROM dbo.TableD codeshared0_ left outer join dbo.[Department] department1_ on codeshared0_.Department_id=department1_.Id left outer join dbo.[TableC] TableC2_ on department1_.TableC_id=TableC2_.Id WHERE codeshared0_.Employee_id in (select emp0_.Id FROM dbo.[Employee] emp0_ left outer join dbo.[Department] department1_ on emp0_.Department_id=department1_.Id left outer join dbo.[TableC] TableC2_ on department1_.TableC_id=TableC2_.Id WHERE emp0_.SomeField_id=2)
16:05:15:250 DEBUG MyApp.Tests - total rows received: 2421
如您所见,使用nH进行读取大约需要15秒,而使用ADO.Net则需要大约2秒。
通过一些研究,我知道nH可能并不意味着用于存储会话中的许多项。您能否想到此问题的任何其他可能原因,或者除了在数据库级别过滤雇员之外的其他建议?
谢谢
- 编辑 -
按照以下建议,我尝试使用Reflection Optimizer(无差异)和IStatelessSession来加载我的集合(引发异常,无状态会话无法获取异常集合)。
我认为我在Department类中的代码必须从干净的地方更改为:
if (this.Employees.Contains(emp))
{
...
}
此\'dirtier \'版本:
var employeesRepository = IOCContainer.Get<IEmployeesRepository>();
if (employeesRepository.EmployeeExists(this,emp))
{
...
}
有人有更好的建议吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)