如今,NHibernate生成的SQL比SP中的手写语句慢吗?

时间:2015-05-27 13:57:03

标签: sql-server nhibernate sql-server-performance

我想知道sql server 2012 db中插入/更新/删除的一般性能,数据量有时达到20米。表中的行。

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

4 个答案:

答案 0 :(得分:2)

简单的答案是:。 NH无法像手写查询一样生成“最佳查询”。

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

您仍然可以用HQL,Linq或SQL编写手写的查询。您通常会失去ORM的好处,但如果您的应用程序中只有少数几个案例对性能至关重要而且不是面向对象。

NHibernate可以进行其他性能优化,用手写SQL很难实现。这些功能对业务逻辑是透明的,不需要太多特殊的开发工作。

这些功能尤其适用于延迟加载和批量大小(预取)。使用手写SQL,您必须在业务逻辑中进行大多数性能优化。如果您的业务逻辑很复杂,那么优化空间就不多了,可维护性会遇到很大问题。在这种情况下,手写DAL的性能和可维护性都会下降并且会产生真正的痛苦。在这种情况下, NHiberate提供更好的性能和更好的可维护性

正如您可能猜到的那样:如果您的业务逻辑不是很复杂,那么手写DAL可以提供最佳性能,而不会有太多可维护性权衡。

因此,请始终为问题选择合适的工具。

示例案例

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

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

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

还有IStatelessSession专为批量操作而设计。

答案 3 :(得分:0)

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

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

NHibernate为您提供了许多调整您的选项 查询。有些可能性是有状态的与无状态的会话,交易,HQL,期货。

如果这仍然不起作用,你可以直接从NHibernate调用SQL语句。这样做的缺点是,如果这对您来说非常重要,您将无法轻松地将代码移植到另一个数据库。