为什么执行存储过程比脚本中的SQL查询更快?

时间:2011-12-19 09:42:10

标签: sql sql-server stored-procedures

事实上,如果我从我的应用程序调用存储过程,我需要连接到我的数据库。

那么,为什么要调用"存储过程"应该比传递SQL查询更快#34;要执行的字符串?

8 个答案:

答案 0 :(得分:57)

SQL Server基本上执行这些步骤来执行任何查询(存储过程调用或临时SQL语句):

1)在语法上检查查询
2)如果没关系 - 它检查计划缓存以查看它是否已经有该查询的执行计划 3)如果有执行计划 - 该计划被(重新)使用并且执行查询 4)如果还没有计划,则确定执行计划 5)该计划存储在计划缓存中以供以后重用 6)执行查询

重点是:临时SQL和存储过程是非常好的没有区别

如果ad-hoc SQL查询正确使用参数 - 无论如何应该防止SQL注入攻击 - 它的性能特征与执行存储过程没有什么不同,并且绝对没有差

存储过程具有其他好处(例如,无需授予用户直接表访问权限),但在性能方面,使用正确的参数化临时SQL查询与使用存储一样高效程序

使用非参数化查询的存储过程

更新更好,主要有两个原因:

  • 由于每个非参数化查询都是对SQL Server的新的,不同的查询,因此必须针对每个查询执行确定执行计划的所有步骤(从而浪费时间) - 并且还浪费计划缓存空间,因为将执行计划存储到计划缓存中最终并没有真​​正帮助,因为该特定查询可能再次执行)

  • 非参数化查询存在SQL注入攻击的风险,应该不惜一切代价避免

答案 1 :(得分:7)

因为每次将查询字符串传递给SQL Server时,代码都必须编译等,存储过程已经编译好并准备好在服务器上运行。

此外,您通过网络发送的数据较少,尽管这通常影响很小。

编辑: 作为附注,存储过程还有其他好处。

1)安全性 - 由于实际查询存储在服务器上,因此您不通过网络传输此信息,这意味着任何拦截网络流量的人都无法深入了解您的表结构。此外,精心设计的SP可以防止注射攻击。

2)代码分离,您将数据库代码保存在数据库中,并将应用程序代码保存在应用程序中,几乎没有交叉,我发现这会使bug修复得更好。

3)可维护性和代码重用,您可以多次重复使用过程而无需复制粘贴查询,如果您希望更新查询,则只需在一个位置更新它。

4)网络流量减少。如上所述,对于大多数人来说这可能不是问题,但是对于大型应用程序,您可以通过切换到使用存储过程来显着减少通过网络传输的数据量。

答案 2 :(得分:4)

您的声明存储过程比SQL查询更快只是部分正确。解释:这些答案中的大多数已经解释了使用存储过程生成和缓存查询计划。因此,如果再次调用存储过程,SQL引擎首先搜索其查询计划列表,如果找到匹配项,则使用优化计划。

传递普通查询不允许这种优势,因为SQL引擎不知道会发生什么,因此找不到匹配的查询。它从头开始创建计划,然后呈现结果。

好消息:您可以使用参数化查询(SQL中的一项新功能)为您的查询启用计划缓存。这使您可以为查询生成计划,并且在您的情况下非常有效,因为您从代码传递的大多数查询保持不变,除了Where子句中的变量。还有一个设置,您可以强制参数化所有查询。在MSDN上搜索此主题,可以帮助您确定最佳选择。

然而,这就是说,存储过程仍然是从应用程序与数据库交互的好方法,因为它提供了额外的安全层。

希望这有用!

答案 3 :(得分:2)

另外一个问题,比较Web服务器和数据库服务器之间的网络流量 -

exec someproc @ var1 ='blah',@ var2 ='blah',@ var3 ='blah'

对此 -

选择field1,field2,field3,field4,field5,field6 .... field30 在table2.field12 = table1.field12上连接table1 等等等等等等 和table1.field3 = @ var1和table2.field44 = @ var2和(table1.field1为null或table1.field1 = @ var3 .......

看到区别?对于99%的我们来说,这可能无关紧要,但对于一些人来说,这可能是高性能应用程序,尽管可能有一些缓存或其他方法来处理这个问题。

我认为很多人声称adhoc查询和存储过程之间没有区别,他们通常使用表作为他们正在使用的ORM的对象存储,这很好。仍有许多重量级数据驱动的企业应用程序,无论是对还是错,都有1000多行存储过程。你可能最终会对它们进行研究。此外,对于那些可能不得不每隔一段时间对生产进行更改并且需要绕过正式流程的人来说,在数据库中比在生产编译代码中更容易做到这一点。改变过程...完成。牛仔,可怕,邪恶,发生。是的,我知道在你的许多人心目中这是一个不可饶恕的罪,剪切的标志......但它确实发生了。也是值得思考的东西。

我知道最新的工具通常会让你使用存储过程很痛苦,如果你希望所有的实体都能很好地为你生成,但是存储的过程仍然有时会占据它们的位置。

答案 4 :(得分:1)

存储过程被编译和缓存。但是,SQL语句将与现有的执行计划进行比较,如果使用匹配,则会使某些优势无效。

多次执行后实际的性能差异是什么?

答案 5 :(得分:0)

与标准SQL语句不同,存储过程由数据库服务器编译和优化。此优化涉及使用存储过程在执行时所需的特定数据库结构的信息。存储执行信息(执行计划)的过程节省了大量时间,特别是如果多次调用存储过程。

存储过程完全在数据库服务器上运行,因此无需通过网络传递大量SQL代码,从而提高了速度。对于一个简单的SELECT语句,这可能没有太大的区别,但是在我们执行一系列循环和计算的情况下,它会产生重大影响。

答案 6 :(得分:0)

  1. 存储过程有时会运行得更快,因为或者尽可能使用RPC调用
  2. SP对于必须重新编译的查询运行得更快 - 例如。 - 在中间某处使用临时表创建

答案 7 :(得分:0)

本文对此进行了很好的解释: https://codingsight.com/dynamic-sql-vs-stored-procedure/

根据我的经验,由于减少了网络流量(不必发送整个查询)以及对过程和查询计划进行缓存,存储过程肯定更快。

我在填充了用户登录数据的表上运行了类似于以下代码的代码。

“从登录名中选择前1个*,其中LogonTime desc按ComputerName = @ ComputerName的顺序排列”

花了2个小时在7000个计算机名称上运行查询。

当我将查询放入存储过程中时,花了大约一分钟才能在7000个计算机名称上运行。

我敢肯定,如果只运行一次查询,则每个查询花费1秒vs 10毫秒对人类没有太大的影响。但是,如果您需要运行一千次查询,则相差1000秒(大约16分钟)与10秒。