NHibernate延迟非常高

时间:2010-02-01 14:23:05

标签: nhibernate orm

我正在将NHibernate用于ORM,并将大量实体的加载合并为一个大查询。

我实际上正在加载一个单词字典,大约500K条目,每个单词与其他单词相关。在后台运行加载过程在我们的应用程序中可能非常棘手,因为我们必须手动加载未按时加载的条目,因为任何时候都可以询问任何单词。我们唯一的要求是尽可能快地加载所有数据。 我也尝试过使用无状态会话,但是有一个例外,即无状态会话无法获取集合(出于某种原因,可能与无状态会话没有缓存的事实有关吗?)

问题是虽然SQLServer中的查询时间不超过25秒,但ICriteria.List()需要3分钟以上。

我使用NHProf来分析加载过程,发现实体的创建是一项代价高昂的事情,它占用了NHibernate的大部分加载时间。

我有什么办法可以减少这种延迟吗?内存分配是昂贵的,还是数据的“填充”?

谢谢!

3 个答案:

答案 0 :(得分:4)

也许您应该考虑这样一个事实:NHibernate(像大多数ORM一样)并不特别适合(或打算)用于这些类型的批量加载方案。你要加载,给予或接受多少行?你想做什么?预先填充缓存?做批处理?

我的直觉是,您应该认真考虑应用的目的,并相应地选择基础技术。也许你可以对你的意图/要求有所了解吗?

编辑好了,从你的评论我明白你在这里尝试做什么。我要做的第一件事是使用原始ADO.NET创建一个简单的原型来加载相同的数据,以获得使用标准数据访问和内存中集合可获得的最佳性能。接下来,使用不同的集合类型来查看填充和搜索时的效果。如果加载这样的数据仍然太慢,是时候开始查看其他加载数据的方法了:基于文件的本地数据文件,保护预序列化对象,某种形式的快速按需加载等等。 / p>

答案 1 :(得分:3)

将500k实体加载到NHibernate会话中并不是一个好主意。该会议是短暂的,并且持有相对较少的实体。

如果你想在NHibernate中进行这种批处理,你应该看看StatelessSession而不是普通的会话。在这种情况下,使用无状态会话很可能会大大提高性能。但是,在使用无状态会话时,您将失去NHibernate第一级缓存的好处,例如更改跟踪。

有关StatelessSession的更多信息可以在this articlein the NH docs的nhibernate.info找到。

在这种情况下,我还建议您考虑使用直接ADO.NET而不是NHibernate。我不是说您应该将整个数据访问策略切换到ADO.NET,但您可能需要考虑使用ADO.NET进行批处理操作,并将NHibernate用于其他情况。

答案 2 :(得分:0)

分析创建过程(例如使用VS性能分析器)应该准确地告诉您什么是昂贵的操作。如果您已经使用延迟加载调优,那么我认为唯一的好解决方案是封装返回的列表以在几次迭代中启用分页返回较小的块。我不确定NHibernate是否支持像JPA那样的惰性结果列表(即在需要之前不从数据读取器加载实体)。