nHibernate 非常慢

Posted

技术标签:

【中文标题】nHibernate 非常慢【英文标题】:nHibernate is painfully Slow 【发布时间】:2011-12-03 04:48:21 【问题描述】:

我们第一次尝试在我的 VS2010 和 Oracle 项目中使用 nHibernate。

应用程序的性能是接受这个项目的关键标准,我们应该在这个项目中使用 nHibernate 吗?

我们正在通过 POC。我们有一个包含 250 列的表,当尝试插入 500 条记录时,应用程序停止运行。

有人可以就 nHibernate 与 PL/SQL CRUD 的性能比较提出建议吗?

不知道我们应该在 nHibernate 配置文件中使用什么参数来获得最佳性能?

我们正在使用以下配置

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory name="DefaultSessionFactory">
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
    <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
    <property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
    <property name="??;</property>
    <property name="show_sql">true</property>
    <property name="use_proxy_validator">false</property>

  </session-factory>
</hibernate-configuration>

感谢期待。

【问题讨论】:

不确定它会产生多大的不同,但是使用 show_sql 并且考虑到您的大量列,NHibernate 将向控制台写入相当多的输出,这不是一个特别快速的操作本身。关闭它,您可能会看到更具代表性的表现。 我不认为这是一个公平的测试。如果你想要绝对 100% 的性能,那么你不应该使用 ORM(在我看来)如果你可以为了使用 ORM 而对性能造成轻微的影响......然后使用 ORM。但是,针对设计不佳的数据库测试 NH 是没有意义的。 发布一些演示问题的示例代码。 如果有一个问题标题无法为您提供有用的答案,那就是那个。 【参考方案1】:

Iridium 关闭 show_sql 的建议是一个很好的建议。如果你使用 log4net,你应该确保你设置了 NHibernate 的日志级别。如果您将级别设置为 DEBUG 应用程序范围,NHibernate 将记录大量条目。

<logger name="NHibernate">
  <level value="ERROR" />
</logger>

【讨论】:

【参考方案2】:

关于 show_sql 和日志记录的建议会产生影响,但即使启用这些建议,您也不应该仅仅因为 nhibernate 而遇到应用程序崩溃的问题。当然,使用 orm 会降低性能,以换取它在可维护性和快速创建应用程序方面提供的所有优点,但在大多数情况下,这还不够重要。

如果您遇到如此严重的性能问题,我建议您的应用程序中存在某些问题。它不仅仅是休眠,使用其他东西会更好(除非你用其他东西做不同的事情)。首先想到的是您应该知道系统中的事务使用的隔离级别。根据您管理会话和事务的方式,您可能使用了比您需要的更高的隔离级别并且不必要地锁定了数据库实体。这可能会导致您所描述的情况以及死锁。 system.transactions 的默认隔离级别是可序列化的,这是大时间锁定,可能不是您想要的。您可以使用以下方法为 nhibernate 生成的事务设置默认值:

<add key="hibernate.connection.isolation" value="ReadCommitted" />

如果你使用system.transactions(transactionscope),你可以在构造函数中指定隔离级别。如果您使用的是 wcf,则有属性和配置以及其他管理方式。如果不了解您的应用程序的更多信息,很难说更多,这实际上只是猜测这是否是您的问题。

【讨论】:

谢谢。我会尝试你的建议。我确定我做错了什么。该应用程序将有超过 300 列,但我尝试使用 4 列实体,插入 100 行需要 30 秒,而使用普通 pl/sql 插入查询需要 2-3 秒。 true 帮助了我,它只需要 3 秒,而之前需要 30 秒。非常感谢。 “帮助的手比祈祷的嘴唇更神圣”【参考方案3】:

我知道你已经接受了答案,但还是想把我的 2c 扔进去。

首先,你在你的一个 cmets 中度过了一天:

应用程序将有超过 300 列

这很晦涩。如果您正在做的是报告,请不要使用 ORM,如果它不报告,那么我会说您的数据库设计得很糟糕,没有理由有 300 列。我不了解 Oracle,但在 SQL Server 中,当行长度超过 8k 时,列在单独页面上的行会影响性能。

生成的查询将非常庞大。你最好使用存储过程而不是使用 ORM。

但我尝试使用 4 列实体,插入 100 行需要 30 秒,而正常的 pl/sql 插入查询需要 2-3 秒

发生这种情况的原因有很多。如果您在数据库中生成身份,则 NHibernate 必须输入另一个选择来检索 Id 以应用于刚刚插入的模型。

让 NHibernate 生成身份可以加快速度,无论是通过 HiLo 还是 Guid/GuidComb。

为每个插入打开一个全新的会话在加起来时也可能代价高昂,为插入重复使用相同的会话,并将插入一起批处理,而不是发送单个语句。 (同样我不知道Oracle是否支持像SQL Server那样的批处理)

无论哪种方式,您都没有提供任何代码来显示您的测试以向任何人说明为什么它对您来说很慢。 NH 能很好地满足 99% 的人们的需求。

【讨论】:

以上是关于nHibernate 非常慢的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate 延迟非常高

Nhibernate 使用

NHibernate体系结构

NHibernate 或 LINQ to SQL [关闭]

NHibernate 执行简单查询需要更长的时间

nhibernate中的命名查询错误