Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么执行存储过程比从脚本查询SQL更快?_Sql_Sql Server_Stored Procedures - Fatal编程技术网

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

为什么执行存储过程比从脚本查询SQL更快?,sql,sql-server,stored-procedures,Sql,Sql Server,Stored Procedures,事实上,如果我从应用程序调用存储过程,我需要一个到数据库的连接 那么,为什么调用“存储过程”应该比“传递要执行的SQL查询”字符串更快呢?存储过程是编译和缓存的。但SQL语句将与现有的执行计划进行比较,如果存在匹配项,则将使用它,从而在某种程度上抵消任何优势 多次执行后的实际性能差异是什么?因为每次向SQL Server传递查询字符串时,都必须编译代码等,存储过程已经编译好,可以在服务器上运行 此外,您通过网络发送的数据也较少,尽管这通常是最小的影响 编辑: 另外,存储过程还有其他好处 1) 安

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


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

存储过程是编译和缓存的。但SQL语句将与现有的执行计划进行比较,如果存在匹配项,则将使用它,从而在某种程度上抵消任何优势


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

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

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

编辑: 另外,存储过程还有其他好处

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

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

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


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

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


存储过程完全在数据库服务器上运行这一事实也提高了速度——不需要通过网络传递大量SQL代码。对于一个简单的SELECT语句,这可能不会有太大的区别,但在执行一系列循环和计算的情况下,它会产生显著的影响。

SQL Server基本上通过以下步骤执行任何查询(存储过程调用或特殊SQL语句):

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

要点是:即席SQL和存储过程在治疗上没有区别

如果一个特殊的SQL查询正确地使用了参数——不管怎样,它应该这样做,以防止SQL注入攻击——那么它的性能特征与执行存储过程没有什么不同,而且肯定不会比执行存储过程更差

存储过程还有其他好处(例如,无需授予用户直接表访问权限),但就性能而言,使用正确参数化的即席SQL查询与使用存储过程一样高效

更新:非参数化查询上使用存储过程更好,主要原因有两个:

  • 由于每个非参数化查询对SQL Server来说都是一个新的、不同的查询,因此它必须为每个查询完成确定执行计划的所有步骤(这样既浪费了时间,也浪费了计划缓存空间,因为将执行计划存储到计划缓存中最终并没有真正的帮助,因为该特定查询可能不会再次执行)

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


您关于存储过程比SQL查询快的说法仅部分正确。解释:大多数答案已经解释了存储过程会生成并缓存查询计划。因此,如果您再次调用存储过程,SQL引擎会首先搜索其查询计划列表,如果找到匹配项,它会搜索我们对优化方案进行优化

传递普通查询不具备这一优势,因为SQL引擎不知道需要什么,因此无法为查询找到匹配项。它从头开始创建计划,然后呈现结果

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

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

希望这是有帮助的

  • 存储过程有时会运行得快一点,因为在可能的情况下,可以使用RPC调用
  • 对于需要重新编译的查询(例如,使用中间的临时表创建),SP运行得更快

  • 另一个被忽略的问题是,比较此服务器的web服务器和数据库服务器之间的网络流量-

    执行someproc@var1='blah',@var2='blah',@var3'