现在 NHibernate 生成的语句比 SP 中的手写语句慢 SQL 吗?

Is NHibernate generated SQL slower than handwritten statements in SP nowadays?

我想知道 insertions/updates/deletes 在 sql 服务器 2012 数据库中的一般性能,数据量有时达到 20 m。 table.

中的行

我可以信任 NHibernate 生成最佳查询吗?

不要盲目相信。有许多方法可以优化 NHibernate 中的查询,例如用于查询的多个 API,包括生成 HQL 或 SQL 查询的能力。

有多种分析工具,包括 NHibernate Profiler,可用于监控查询和一般性能。

还有专为批量操作设计的IStatelessSession

这取决于您所谓的最佳查询以及您的数据模型如何适合您的数据库模型(表)。

您可以记录所有语句,因此 NHibernate 正在做什么以及它使用什么 SQL 语句来查询或更新数据库是透明的。

NHibernate 为您提供了许多选项来调整您的 查询。一些可能性是有状态与无状态会话、事务、HQL、期货。

如果这仍然无法按照您的预期进行,您可以直接从 NHibernate 调用 SQL 语句。这样做的缺点是,如果这对您很重要,您将无法轻松地将代码移植到另一个数据库。

使用 NHibernate 或任何 ORM 是一种选择,与使用 SQL 和 SP 的代码相比,大多数选择具有更易于维护的代码。

在某些情况下,与 SP 相比,它生成查询的速度可能不够快,而且其中许多情况可能没有明显的性能问题。但是,如果不是这种情况,您始终可以使用 SP 并使用 NHibernate 调用 SP。

简单的答案是:。 NH 无法像手写查询那样生成 "optimal queries"。

它通常从数据库中获取数据以在内存中创建对象。因此,例如,默认情况下它总是选择 table 中的所有列。它也尝试通过始终生成具有相同参数的相同查询来优化 SQL 编译时间。

您仍然可以在 HQL、Linq 或 SQL. 中手写查询您的应用程序中的案例对性能至关重要,而且面向对象的程度不高。

NHibernate 可以进行其他性能优化 手写很难做到SQL。而且这个特性对业务逻辑是透明的,不需要太多特殊的开发工作。

这些功能尤其是在延迟加载和批量大小(预取)方面。使用手写 SQL,您必须在业务逻辑中进行大部分性能优化。如果您的业务逻辑很复杂,那么 space 优化和可维护性就会成为一个大问题。在这种情况下,手写 DAL 的性能和可维护性都会下降,并且会带来真正的痛苦。在这种情况下,NHiberate 提供更好的性能和更好的可维护性

正如您所猜测的那样:如果您的业务逻辑不是很复杂,手写 DAL 可以提供最好的性能,并且不会有太多的可维护性折衷。

所以总是选择正确的工具来解决问题。

示例案例

应用程序具有处理订单的功能。它获得一个主键作为参数。它使用数据库中的订单项目加载订单,它需要有关用户和产品、位置、税收、邮政费率、特价商品等信息。所以这是一个非常复杂的事情。查询优化不是什么大问题,因为大多数查询本质上都是微不足道的。

四年后,您的老板想要一个 "batch process" 可以处理数百个订单的地方。所以你必须在循环中调用你的函数。第一个问题:您通过优化查询获得要处理的订单。但是您的函数将主键作为参数并再次加载订单。下一个问题:所有关于产品、位置等的相关数据都需要为每个订单再次加载,即使它们在大多数情况下是相同的(但并非总是如此)。所以它开始表现得很糟糕。您尝试为已经从数据库加载的内容实现一些缓存。很难管理此数据的更改,因为您在数据库中有一个版本,在缓存中有一个版本。因此,您会尽力而为,直到它表现得足够好,同时您失去了对 "batch process" 出现之前非常好的代码的控制。无论接下来出现什么功能,它都会杀死您。

对于 NHibernate,它看起来大不相同。您不必传递主键。您有从数据库中加载一次的对象(可能是代理并且只包含主键)。当从订单导航(与使用其他查询相反)到产品、位置和所有内容时,对象仅在第一次使用时加载一次。由于可配置的批量大小,NH 会为一些稍后处理的订单预取产品、位置等,因此它避免了额外的查询。您的代码基本上只包含您需要执行的计算,并且没有提高性能所需的复杂内容。 (好吧,这就是完美世界中的样子,但实际上已经很不错了)。