我的问题是,从数据库中获取记录时,NHibernate的指数速度会呈指数级增长。我有一个请求,基本上从一个非常大的数据库中提取所有数据,以便在报告中使用。
我想,因为我不能一次性获得所有记录,因为记录集太大了,我想尝试分解它。基本上我正在迭代索引的范围,即。记录id x到y,然后y + 1到z,依此类推。
每个结果集约为10megs。前20个左右拉动每个不到一分钟,然后在下一次拉动时,需要10分钟,然后是30分钟和1小时。我在那里停止了程序,不想等到下一次拉动。我从我离开的索引开始再次运行程序,再次,前20个左右的拉动非常快,然后由于一些奇怪的原因,有一个重大的减速。
非常感谢任何帮助。
答案 0 :(得分:8)
NHibernate为你做了很多工作,这可能会减慢它的速度。它保留了你在会话中拉出的对象,这基本上是一级缓存。当您运行查询时,它将检查该组对象以查看是否需要将它们刷新回数据库(可能您已经更改了它们,以便它们现在可以作为查询的结果!)。因此,一个强大的可能性是,您的查询正在秘密地遍历大量对象,试图在将查询发送到数据库之前弄清楚它应该写入到数据库。
如果是这种情况,您可以尝试定期session.Clear()或session.Evict(object)从缓存中删除对象,以便NH不会尝试使数据库与它们保持一致。如果您希望NH“注意”它们,您可以随后重新附加对象。
修改:或使用无状态会话。这是一个example。
答案 1 :(得分:3)
作为选项,您可以尝试使用StatelessSession。它不会跟踪所有拉出的对象,也不会减慢您的应用程序的速度
答案 2 :(得分:1)
有几种方法可以提高NHiberante的性能
如果您描述的时间过长,我认为上述任何内容都不会对您有效。
NHibernate不适用于大型数据集。 NHibernate对于应用程序中使用的大多数查询都很有用,特别是对于没有比在一个屏幕上呈现给用户的结果多得多的查询。如果要在应用程序的某些部分中使用较大的数据集,则在数据集增加时,使用的任何工具所支付的每个小的性能损失都会变得很大。 (不幸的是)只能通过普通的sql达到最大性能。
答案 3 :(得分:1)
很可能的原因是缺少索引。建议您在这些表上发布查询,表定义和当前索引。
对于报告,您可能需要创建一个存储过程(如果涉及大量聚合,甚至可能需要索引视图),并使用NHibernate包装它。
我还会启动SQL事件探查器以查看正在执行的查询。