为什么存储过程比查询快

50

我想编写一个简单的单行查询来从数据库中选择一个值。

如果我为此查询编写存储过程而不是在C#代码中编写简单的选择查询,那么我相信这个简单的选择查询的存储过程会更快,但是为什么呢?

我对存储过程和在代码中编写简单查询之间的区别感到困惑。我不明白为什么存储过程比直接在代码中编写一个简单的查询更快?


@Cuong Le 我在谷歌上搜索并发现存储过程甚至比简单查询更快,但没有清楚的想法为什么? - Ammar Raja
@Coung Le 如果两者性能相同,那么很明显我们只是出于安全原因使用存储过程吗??? - Ammar Raja
你说的“安全原因”,是指SQL注入吗? - cuongle
@CuongLe 的意思是问我们是否使用存储过程来保护我们的应用程序免受黑客攻击? - Ammar Raja
1
这是第二个神话,安全是一个跨层次的关注点,应该从表示层向下延伸到其他层。这并不意味着使用SQL就容易被黑客攻击。 - cuongle
显示剩余2条评论
5个回答

96

存储过程比SQL代码更快

这是个谬论,性能始终相等。引自书籍:《为企业架构微软® .NET解决方案》

SQL是一种语言,通过它您可以声明有关在数据库上执行的操作(查询、更新或管理操作)的意图。数据库引擎得到的都是文本。就像编译器处理的C#源文件一样,SQL源代码必须以某种方式编译,以产生一系列较低级别的数据库操作——这个输出称为执行计划。从概念上讲,生成执行计划可以看作是编译程序的数据库对应物。
存储过程相对于普通SQL代码所谓的性能提升在于执行计划的重用。换句话说,第一次执行存储过程时,DBMS会生成执行计划,然后执行代码。下一次它将只重用先前生成的计划,从而更快地执行命令。所有的SQL命令都需要一个执行计划。
(虚假的)神话是DBMS仅针对存储过程重用执行计划。就SQL Server和Oracle DBMS而言,重用执行计划的好处适用于任何SQL语句。引用SQL Server 2005在线文档的话:
“当在SQL Server 2005中执行任何SQL语句时,关系引擎首先查找过程缓存,以验证是否存在相同SQL语句的现有执行计划。SQL Server 2005重用它发现的任何现有计划,节省重新编译SQL语句的开销。如果不存在现有的执行计划,SQL Server 2005为查询生成一个新的执行计划。”
关于SP比普通SQL代码表现更好的争论是毫无意义的。就性能而言,任何命中数据库的SQL代码都会被同样处理。一旦编译完成,性能是相等的。

2
你点中了我的思维。需要从你的角度再次学习它。感谢你提供了不同的观点。 - muhammad kashif
1
存储过程非常适用于加速某些数据库操作...然而,在“创建”存储过程时,使用SET NOEXEC ON将有助于预编译SP(SQL语句).. :) - Muhammad Azeem
4
@muhammadkashif说的内容已经过时了,存储过程(SP)已经是10年前的技术了。现在的趋势是使用ORM并在代码中动态生成SQL语句。存储过程难以维护,如果需要调试SQL代码也非常痛苦。 - cuongle
1
需要补充的一点是 - 至少根据这些文档,"在缓存中匹配新SQL语句到现有未使用的执行计划的算法要求所有对象引用都必须是完全限定的"。 - Matt Johnson-Pint
2
好的,通常普通SQL语句会命中缓存,速度和存储过程一样快。但是对于那些执行频率不高、非常复杂的查询语句来说呢?这些查询是否容易错失缓存,并且它们是否仍能从存储过程中受益?或者说存储过程根本没有事先编译好,而是和普通查询一样使用相同的缓存? - Jan-Willem Gmelig Meyling
显示剩余4条评论

5

1

这取决于查询的复杂程度,对于简单的查询,最好将其编写并执行为一个查询本身。然而,当您需要在数据库端进行更多的处理(例如,您想要在游标中获取数据并进行操作等),存储过程更好,因为它们在数据库服务器上执行,并避免了不必要的开销,如解析和额外的通信。


是想说存储过程不适合简单的单个查询吗? 我应该直接编写单个简单查询,而不是将其编写为存储过程吗? - Ammar Raja
存储过程非常适合加速某些数据库操作。 - Muhammad Azeem
我的意思是,在某些情况下,静态查询比使用存储过程更好。特别是对于简单的查询。干杯! - wizgot

-2

存储过程是数据库中的存储查询。它们是预编译的。当您请求数据库执行存储过程(SQL Server)时,SQL Server已经具有存储过程的执行计划。而简单的查询需要在运行时创建它们的执行计划。您需要在这里学习更多。


这就是为什么存储过程比即席查询更快的原因。 - Muhammad Azeem
@muhammad kashif 谢谢 :) 我阅读了你的链接,现在我的思路清晰了。 - Ammar Raja
9
这纯粹是不正确的 - 请参考被接受的答案。 - marc_s

-3

存储过程是预编译和优化的,这意味着查询引擎可以更快地执行它们。相比之下,代码中的查询必须在运行时解析、编译和优化。这一切都需要时间。


4
这完全是不真实的 - 请查看被接受的答案。 - marc_s

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接