【问题标题】:NHibernate - Retrieving Lots of Data Becomes Exponentially SlowNHibernate - 检索大量数据变得非常缓慢
【发布时间】:2010-12-23 05:48:40
【问题描述】:

当我在 NHibernate 中检索大量数据时(例如在生成报告时),我遇到了一个问题,该页面需要检索的数据越多,速度就越慢。我找到了以下文章:

http://nhforge.org/blogs/nhibernate/archive/2008/10/30/bulk-data-operations-with-nhibernate-s-stateless-sessions.aspx

它解释了在 NHibernate 中进行批量数据操作是如何缓慢的,因为第一级缓存变得太大,以及应该如何使用 IStatelessSession。我遇到的麻烦是我不想将我的应用程序绑定到 NHibernate,所以我在 ISession 周围添加了一个包装器。然后我使用 Linq 作为我的查询机制,但 IStatelessSession 不支持 Linq(它可能在 NHibernate 3 中支持,但目前 Linq 提供程序并不稳定)。

然后我读到,您可以在多次迭代后进行清除以清除一级缓存。现在的问题是你不能使用延迟加载。 linq 提供程序不允许您覆盖定义的映射(或急切地获取附加数据),因此每当我在清除会话后抓取延迟加载的数据时,都会引发异常。

我完全不知道现在该做什么。我喜欢使用 linq 轻松生成报告,但 NHibernate 中内置 linq 提供程序的限制似乎阻碍了我。

如果有人能告诉我另一种方法,我将不胜感激。谢谢

【问题讨论】:

  • 检索大量数据是什么意思?您是在谈论带有一些关系数据的 10 行还是 1000 行或行?如果您要检索 > 100 行,我会说您做错了。你能解释一下你的场景(不是你的问题)吗,因为它可能只是你的场景错了。
  • 嗨,Phil,我们说的可能是 1000 行。这是一次性报告,所以我不介意这需要几分钟,但目前如果我记录 100 条记录需要 5 分钟,20 条记录需要 15 分钟,30 条记录需要一个多小时。你会注意到我试图达到的指数级增长。
  • 所以问题实际上不是检索记录并显示它们,而是处理记录?在数据库中做了多少,在代码中做了多少?您能否提前预先计算数据,以便在生成报告时不会进行太多处理,主要只是检索。此外,如果您有 joins/where 条件,您是否对查询进行了概要分析以查看它在哪里运行缓慢。
  • 在不了解您的类、映射和 LINQ 查询的情况下很难回答这个问题。您确定您没有遇到 SELECT N+1 问题,因为这通常会随着记录数量的增加而导致指数级减速。适当放置的连接或映射修改通常可以解决问题。因此,我们将不胜感激。
  • 大家干杯。有关我如何解决延迟加载和 select n + 1 问题的更多信息,请参阅我对标记答案的回复。

标签: nhibernate


【解决方案1】:

我很确定这不受 ICriteria 或 Linq 方法的支持;但是,您可以考虑为此使用 hql 命名查询。在映射上设置"read-only" 属性将阻止实体在会话中被跟踪。更多信息可以在here找到。

由于这与您的使用有关,我不会担心无法在 linq-to-nhibernate 的上下文中执行所有操作。尽管它非常适合处理大多数场景,但像报告这样的特殊用途通常最好留给 hql 甚至原生 sql 等方法。不要害怕在您的存储库中拥有一些 .GetEntitySummaryReport() 方法,这不是世界末日。

更新

如果感觉向您的存储库添加方法错误,我建议使用Enhanced Query Object,它提供了一种以与提供者无关的方式封装专门查询的好方法。

【讨论】:

  • 嗨,丹,为您的建议喝彩。针对存储库的额外方法是一种想法,但这确实意味着如果我计划将我的应用程序升级到实体框架,我将不得不做一些额外的工作。理想情况下,我想在 Linq 工作。
  • 我最终将其他方法添加到我的存储库中。我想如果我打算升级的话,我只需要做一些工作。我确实使用过的一个选项是使用 Expand 急切地加载数据,这使我能够清除会话。这没关系,但对于理想的性能,您的建议有效。
猜你喜欢
  • 1970-01-01
  • 2019-11-11
  • 1970-01-01
  • 2016-09-19
  • 1970-01-01
  • 2017-04-22
  • 1970-01-01
  • 2013-01-19
  • 1970-01-01
相关资源
最近更新 更多