存储程序更加有效,在一般情况下,比联陈述的现代化数据库的?[重复]

StackOverflow https://stackoverflow.com/questions/59880

  •  09-06-2019
  •  | 
  •  

这个问题已经有一个答案在这里:

传统的智慧的国家存储程序总是更快。所以,因为他们总是速度更快,使用它们 所有的时间.

我很确定这是基于一些历史背景在此是一旦情况。现在,我不主张存储的过程是不必要的,但我想知道在什么情况下存储程序是必要的,在现代化的数据库如MySQL SQL服务器、Oracle、或 <Insert_your_DB_here>.它是矫枉过正的所有访问过存储程序?

有帮助吗?

解决方案

注意到 这是一般性的看存储程序没有规定向一个特定的 DBMS。一些DBMS(甚至是,不同 版本相同的DBMS!) 可以操作 与此相反,所以你会想要 仔细检查你的目标DBMS 之前假定这一切仍然成立。

我已经Sybase ASE,MySQL SQL服务器DBA上由于几乎十年(随着应用程序开发在C,PHP,PL/SQL,C#.NET和红宝石).所以,我没有特别的斧头磨在这个(有时)的神圣战争。

历史性的益处存储的过程通常是从下面的(在任何特定顺序):

  • 预析SQL
  • 预产生查询执行计划
  • 减网络延迟
  • 潜在缓好处

预析SQL --类似的好处,以汇编与解释码,除了在一个非常微的水平。

仍然是一个优势? 不是很明显在现代CPU,但是如果你发送一个单一的SQL发言,是非常大的eleventy亿次,分析开销可能会增加。

预产生查询执行计划.如果你有许多人加入的排列组合可以增长非常难以控制(现代化的优化有限制和截止于业绩原因)。它不是未知的,用于非常复杂的SQL有不同的、可衡量(我看见了一个复杂的查询需要10秒只是为了生成一个计划,在我们调整了DBMS)的延迟时间由于优化程序试图找出"最近"执行计划。存储程序,一般来说,储存这在记忆,这样就可以避免这种开销。

仍然是一个优势? 最DBMS'(最新版)将缓查询计划为个别SQL发言,大大降低了业绩之间的差存储的过程和特别SQL。有一些注意事项和情况不是这种情况,所以你需要测试你的目标DBMS。

此外,越来越多的DBMS允许提供优化的道路计划(摘要查询计划)以显着地减少优化的时间(对两个临时和存储的过程SQL!!).

警告 缓存的查询计划不是一个性能的灵丹妙药。偶尔会查询计划,该计划是产生十分理想。例如,如果发送 SELECT * FROM table WHERE id BETWEEN 1 AND 99999999, ,DBMS可能选择一个 全表扫描而不是索引 扫描因为你是抓住每一个行 在表格(所说的 统计)。如果这是缓存 版本,然后你可以得到可怜 性能当你后来发送 SELECT * FROM table WHERE id BETWEEN 1 AND 2.背后的推理是这个 范围之外的这张贴,但是 进一步阅读见: http://www.microsoft.com/technet/prodtechnol/sql/2005/frcqupln.mspxhttp://msdn.microsoft.com/en-us/library/ms181055.aspxhttp://www.simple-talk.com/sql/performance/execution-plan-basics/

"总之,他们确定 提供的任何其他的 共同价值观的时候编译或 重新编译进行了 优化程序编制和缓存 查询计划,特别是 值。然而,当进行查询的计划是 重新用于随后的执行 同样查询为共同的价值观 (M','R',或'T'),它导致了 次佳的业绩。此 子的最佳性能的问题 存在,直到查询 重新编译。在这一点上,基于 该@P1参数值提供的, 查询可能会或可能没有 绩效问题。"

减网络延迟 A)如果运行的相同SQL遍又一遍-和SQL增加了许多KB的代码--的更换,一个简单的"exec foobar"可以真正增加。B)保存处可用于移动程序代码转DBMS。这样可以节省洗牌的大量数据的客户只有把它发送一个涓流的信息回(或根本没有!).类似于这样做的一个加入DBMS与在代码(每个人都喜欢你!)

仍然是一个优势? A)现代的1gb(和10gb了!) 太真正使这个可以忽略不计。B)取决于如何饱和网络--为什么把几个兆字节的数据来回没有很好的理由?

潜在缓好处 执行服务器的端转变的数据可能更快,如果你有足够的存在DBMS和你需要的数据是在存储器的服务器。

仍然是一个优势? 除非你的应用共享存储器访问DBMS的数据,边缘总会存储的过程.

当然,没有讨论的存储程序优化将是不完整的讨论的参数和特设SQL。

参数化/准备的SQL
种之间的交叉存储的过程和特设SQL,它们是嵌入式SQL报表在一个主机语言使用的"参数",用于查询的价值观,例如:

SELECT .. FROM yourtable WHERE foo = ? AND bar = ?

这提供了一个更广义的版本的查询,现优化可以使用高速缓冲存储器(和重复使用)查询执行计划,导致在许多绩效益的存储程序。

特设SQL 只是打开一个窗口控制台DBMS和类型在SQL发言。在过去,这些都是"坏的"表演者(月平均)由于DBMS没有办法预化查询的参数化/存储程序的方法。

仍然是一个缺点? 不一定。最DBMS有能力的"抽象"的特设SQL入参数化的版本--因此或多或少否定之间的差异。一些这样做隐含地或必须启用的命令设置(SQL服务器: http://msdn.microsoft.com/en-us/library/ms175037.aspx Oracle: http://www.praetoriate.com/oracle_tips_cursor_sharing.htm).

汲取的教训? 摩尔法继续在和DBMS优化,与每一个释放,获得更加复杂。当然,你可以把每一个愚蠢的小SQL statement内存储的过程,但是只知道这一程序工作上的优化很聪明,是在不断寻找各种方法,以提高性能。最终的(如果它不在这里已经)特设SQL能会变得难以区分(在平均!) 从存储程序的性能,因此任何类型的 大规模的 存储程序使用的**仅仅为了"性能的原因"**肯定听起来像是过早的优化给我。

无论如何,我认为如果你避免的边缘情况,并有相当香草SQL,你不会注意到,差异之间的临时和存储的过程。

其他提示

原因使用存储程序:

  • 减少交通网络 -你必须送SQL statement全网络。与sprocs,可以执行SQL在批次,也是更有效率。
  • 缓存的查询计划 -第一次sproc执行,SQL服务器创建一个执行计划,该计划是缓存的再利用。这是特别高性能对于小的查询的运行频繁。
  • 能够使用的输出参数 -如果你发送的内联SQL,返回一行,你只能找回一个记录集。与sprocs你可以让他们回来以输出参数,这是相当快。
  • 权限 -当你发送的内联SQL,你得授予的权限上表(s)的用户,这是给予更多的访问不仅仅是授权执行一个sproc
  • 分离的逻辑 --除SQL-产生的代码和分离它的数据库。
  • 编辑能力没有重新编译 -这可能会引起争议。你可以编辑SQL sproc没有必要重新编译程序。
  • 找到一个表用 -与sprocs,如果你想要找到的所有SQL发言引用的特定表,可以出口的sproc码和搜索它。此更容易,而不是试图找到它的代码。
  • 优化 -这是更容易一DBA优化SQL和调整的数据库时sprocs的使用。很容易找到丢失的索引等。
  • SQL注入攻击 --适当地写入联SQL可以抵御的攻击,但sprocs是更好地为这种保护。

在许多情况下,储存程序实际上是较慢,因为他们更genaralized.同时存储程序可以高度的调整,以我的经验有足够发展和体制的摩擦,他们留在原处,一旦他们的工作,所以存储程序通常倾向于返回很多的栏"只是在情况下"-因为你不想部署一个新的存储程序的每一次你改变你的应用程序。一个或/M,另一方面,仅请求列应用程序使用,这减少了对网络业务量,不必要的加入,等等。

这是一个辩论,即肆虐和上(例如, 在这里,).

这是为便于编写坏的存储程序,因为它是写不好的数据取逻辑在你的程序。

我倾向于储存处,但那是因为我通常的工作非常大和复杂的应用程序在企业环境,其中有专门的数据库管理员负责保持数据库服务器上运行的甜蜜。

在其他情况下,我很高兴足够的数据访问的技术,例如皇宫照顾的优化。

纯粹的性能不是唯一的考虑因素,虽然。的方面,例如安全性和配置管理通常至少作为重要的。

编辑:同时弗兰斯Bouma的文章确实是详细的,这忽略了一点关于安全通过一英里。事实上,它是5岁并不能帮助其相关性。

没有明显的速度差别对于储存程序vs参数化或准备的查询,上最现代化的数据库,因为该数据库还将缓执行计划对于那些查询。

注意到参数化的查询不同的特设sql。

主要原因,海事组织仍然有利于存储的过程今天已更多地与安全。如果您使用的存储程序 , 你可以禁止插入、选择、更新、删除、更改、降,并创建等的权限应用程序的用户,只有离开其与执行。

这提供了一些额外的保护对 第2次了 sql注射。参数化查询的唯一保护对 第1次了 注射。

显然,实际性能,应该可以测量在个别情况下,不能假定。但是,即使在情况下的性能 阻碍 由存储程序,也有很好的理由使用他们:

  1. 应用程序开发者并不总是最佳的SQL程序员。存储程序隐藏SQL从应用程序。

  2. 存储程序自动使用结合变量。应用程序开发人员通常避免结合变量,因为它们似乎是不必要的代码,并显示小小的好处在小型试验系统。后来,未使用结合变量可以调节数据库的性能。

  3. 存储程序,创建一个间接层,可能是有用的。这是可以改变的执行情况的详细资料(包括表结构)在数据库侧没有接触应用程序的代码。

  4. 该运动的创造存储程序可用于记录所有数据库相互作用的系统。它更易于更新的文件,当事情变化。

这就是说,我通常坚持的原SQL在我的应用程序使得我可以控制它自己。这取决于你的开发团队和哲学。

一主题,目前还没有人提到作为受益的存储程序的安全。如果建立应用程序,专用数据接入存储程序,可以锁定的数据库,这样的唯一访问是通过那些存储程序。因此,即使有人获取一个数据库号和密码,他们将被限制在什么他们可以看到或是做的对这一数据库。

在2007年,我在一个项目,在这里我们使用MS SQL服务器经由奥姆.我们有2大,越来越表了达到7-8秒钟的负载时的上SQL服务器。后2个大型存储SQL程序,并优化它们的查询计划,每个数据库载时得到了小于20毫秒,所以显然仍有效率的原因以使用存储SQL程序。

在这样说之后,我们发现,最重要的好处的存储程序是加入维护保养-轻松、安全、数据完整性,并耦的业务逻辑从中间件的逻辑,惠及所有中间件的逻辑再利用的2的程序。

我们的奥姆供应商作出通常的要求,发射许多小SQL查询将要被更有效获取大,加入数据集。我们的经验(给我们带来惊喜)表明其他东西。

这当然可能变化之间的机、网络、操作系统、SQL服务器、应用程序框架,奥姆框架和语言的实现,所以衡量的任何收益,你认为你可能会做别的东西。

它不是直到我们的基准,我们发现问题之间的奥姆和数据库,把所有负荷。

我更喜欢使用SP时候,它使用它们。在SQL服务器无论如何没有性能优点SP是在一个参数化查询。

然而,在我目前的工作我的老板提到,我们被迫使用SP是因为我们客户的需要。他们觉得他们更加安全。我没有在这里足够长的时间来看看如果我们要实现基于角色的安全,但我感觉我们做的。

所以,客户的感情,特朗普的所有其他参数,在这种情况。

我的一个优点存储程序是以主机的语言无关:你可以从一C,Python,PHP或任何应用程序的另一种编程语言没有重写代码。此外,一些功能,如批量行动提高真正的业绩并不容易(不是所有的?) 在主的语言。

读过弗兰斯Bouma的 优秀后 (如果一位有偏见)。

所有我能说的是SQL服务器。在这一平台,储存程序是可爱,因为服务器储存的执行计划,这在大多数情况下,加速性能好一点.我说"在多数情况下",因为如果SP具有广泛不同的路径的执行你可能会得到次优的性能。然而,甚至在那些情况下,一些开明的重构的SPs可以加快速度。

使用存储程序污物的操作可能是矫枉过正,但这将取决于该工具被用和自己的偏好(或要求)。我更喜欢内联SQL,但我一定要使用的参数化的查询,以防止SQL注射攻击。我一直打印出来的这个 热门的漫画 作为一个提醒,什么可能错如果你不小心。

存储程序可以有真正的业绩的好处工作时与多个集的数据,返回一个单一的数据集。它通常更有效地处理集中数据存储程序比向他们发送的电线以处理的客户机结束。

意识到这是一个有点离题的问题,但是如果您使用的是一个很大的贮存程序,确保有一个一致的方式来把它们放在某一类源的控制(例如,颠复或git)和能迁移的最新动态发展系统的试验系统生产系统。

当这样做是通过一方面,没有方式容易地审计什么代码在哪里,这个迅速变成一场噩梦。

我不知道他们是速度更快。我喜欢用格林对数据的访问(不要重新发明轮子)但是我意识到,并不总是一个可行的选择。

Frans Bouma具有良好的关于这个问题的文章: http://weblogs.asp.net/fbouma/archive/2003/11/18/38178.aspx

储存过程是伟大的情况下SQL码是经常运行,因为该数据库存储了它的标记在记忆。如果你再跑了同样的代码之外的储存proc,你会喜欢收性能打从数据库中重新分析将同样的代码。

我通常常被称为代码作为一个存储proc或作为SqlCommand(.网)目的和执行的很多次作为必要的。

是的,他们是最快的时间。SQL组成是一个巨大的调整性能的区域。如果我在做一个回办公室类型的应用程序,我可以跳过他们,但是任何生产面临的我把它们用于确定所有原因他人讲过...即安全。

恕我直言...

限制"C_UD"操作存储程序可以保持数据的完整性逻辑在一个地方。这也可以通过限制"C_UD"操作一个单一的中具层。

读取的行动可以提供给应用程序,以便他们可以加入仅表/列,他们的需要。

存储程序也可以用来替代参数化查询(或临时查询)对于其他一些优点:

  • 如果你需要正确的东西(排列顺序等)。 你不需要重新编译程序
  • 你可以拒绝访问的所有表格,用户账户,授予访问权限只要存储的过程和路线的所有访问过存储程序。这样你可以有自定义验证的所有输入更多的灵活表的约束。

减少交通网络--SP一般是更坏的然后动态SQL。因为人们不创建一个新的SP对于每一个选择,如果你需要的只是一个列被告知使用SP已列,他们需要,而忽略其余部分。得到一个额外的列和任何网络使用你刚刚走了。你也往往有很多的客户过滤当SP的使用。

缓存--MS SQL不享他们的任何不同,不是因为MS SQL2000可能的一直7但是我不记得了。

权限--不是一个问题,因为几乎我所做的一切都是网或者有一些中间申请层的所有数据库的访问。唯一的软件,我的工作有直接的客户数据库的访问是第3个缔约方的产品是专为用户直接访问,并根据给予用户权限。是MS SQL权限的安全模式吮吸!(没有花时间在2008年尚未)作为最后的一部分,以此希望看到一项调查的如何许多人仍然在做的直接客户/服务器编程vs网和中的应用程序服务器编程;如果他们正在做的大型项目为什么没有奥姆.

分离--人们会问为什么你把业务逻辑以外的中间层。如果你还是想单独的数据处理码有办法这样做,而不把它的数据库。

编辑能力-什么你有没有测试,以及版本控制你要担心的?也只有一个问题与客户/服务器、网络世界没有问题。

找到表--只有如果你可以识别的SP使用它将坚持与工具的版本控制系统,剂洗劫或些工作室找到的。

优化--DBA应使用工具的数据库找到的查询需要的最优化。数据库可以告诉DBA什么样的声明是在谈论的大多数时间和资源,他们可以修复。对于复杂的SQL发言的程序应该被告知谈话的DBA如果简单的选择不要担心它。

SQL注的攻击--SP没有提供更好的保护。他们唯一得到的点头是,他们中的大多数教学使用的参数vs动态SQL大多数例子忽略的参数。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top