为什么NHibernate生成的参数化SQL与存储过程一样快?

时间:2020-03-05 18:49:33  来源:igfitidea点击:

我的一位同事声称,即使缓存了执行路径,从ORM生成的参数化SQL也无法像存储过程一样快。这个顽固的开发人员有什么帮助吗?

解决方案

回答

我将从阅读本文开始:

http://decipherinfosys.wordpress.com/2007/03/27/using-stored-procedures-vs-dynamic-sql-generation-by-orm/

这是两者之间的速度测试:

http://www.blackwasp.co.uk/SpeedTestSqlSproc.aspx

回答

对于大多数人而言,说服他们的最佳方法是"向他们显示证据"。在这种情况下,我将创建几个基本的测试用例来检索相同的数据集,然后确定使用存储过程与NHibernate所花费的时间。获得结果后,将其移交给他们,大多数持怀疑态度的人应屈服于证据。

回答

第一轮我们可以启动事件探查器跟踪并比较执行时间。

回答

对其进行衡量,但要以非微观基准衡量,即代表我们系统中实际操作的事物。即使存储过程在性能上有很小的好处,它对代码所产生的其他成本也将是微不足道的:实际上是检索数据,对其进行转换,将其显示等。更不用说使用存储过程等同于扩展逻辑在应用程序和数据库中没有明显的版本控制,单元测试或者后者的重构支持。

回答

自己进行基准测试。编写一个测试床类,该类执行一个采样存储过程数百次,并以相同的次数运行NHibernate代码。比较每种方法的平均执行时间和中值执行时间。

回答

如果每次查询都相同,则速度一样快。不论SQL来自何处,SQL Server 2005都会在批处理中的每个语句级别缓存查询计划。

长期的差异可能在于,存储过程对于DBA而言要容易得多且好很多倍,而DBA则必须从探查器跟踪中收集数百种不同的查询,这是一场噩梦。

回答

我已经多次争论过这个问题。
几乎总是我最终会获得一个非常好的dba,并在运行事件探查器的情况下运行proc和一段代码,并获得dba以表明结果是如此微不足道。

回答

测量它。

确实,在我们进行衡量之前,任何关于此主题的讨论都可能是徒劳的。

回答

这是Franz Bouma的文章的另一个链接。

关于存储过程如何扩展的另一篇文章。

和CodingHorror当然有关存储过程的问题。

回答

对于他正在考虑的特定用例,他可能是正确的。对于某些可以任意调整的复杂SQL,存储过程的执行速度可能更快。但是,从休眠之类的东西中获得的东西就是缓存。在实际应用程序生命周期中,这可能会证明快得多。

回答

这里的问题是我们已经接受了举证责任。我们不太可能像这样改变别人的想法。不管喜欢与否,人们甚至是程序员都太激动了,以至于不易被逻辑所左右。我们需要将举证责任放回给他,让他说服我们,否则将迫使他进行研究并为自己找到答案。

使用存储过程的一个更好的说法是安全性。如果仅使用存储过程,而没有动态sql,则可以为应用程序数据库用户禁用SELECT,INSERT,UPDATE,DELETE,ALTER和CREATE权限。这将保护我们免受大多数二阶SQL注入,而参数化查询仅对一阶注入有效。

回答

我只会在Rob的回答中添加几句话:

首先,确保测试用例中涉及的数据量与生产值相似。换句话说,如果查询通常针对具有成千上万行的表,则创建这样的测试环境。

其次,除了使用nHibernate生成的查询和s'proc调用之外,使其他所有条件均相等。希望我们可以通过简单地换出提供程序来执行测试。

最后,意识到与存储过程和ORM相比,通常存在更多的风险。考虑到这一点,测试应该考虑所有因素:执行时间,内存消耗,可伸缩性,调试能力等。

回答

添加的抽象层将导致它比纯调用sproc慢。仅仅由于我们在托管堆上有其他分配,并且在调用堆栈上有更多的推入和弹出操作,事实是,与让ORM建立查询相比,调用sproc效率更高,无论其性能如何。 ORM是。

甚至可以衡量的缓慢程度值得商bat。大多数ORM具有缓存机制可以完全避免执行查询,这也为我们提供了帮助。

回答

即使存储过程的速度提高了10%(可能不是),我们也可能要问自己这到底有多重要。最后真正重要的是为系统编写和维护代码有多么容易。如果我们正在编写Web应用程序,并且所有页面都在0.25秒内返回,那么使用存储过程节省的额外时间可以忽略不计。但是,使用像NHibernate这样的ORM可能有许多其他优点,而仅使用存储过程很难复制它们。