17

即席查询 vs 存储过程 vs 动态 SQL。谁能说说优缺点?

4

6 回答 6

31

存储过程

  • 优点:适用于简短的简单查询(又名 OLTP——即添加、更新、删除、查看记录)
  • 优点:将数据库逻辑与业务逻辑分开
  • 优点:易于排除故障
  • 优点:易于维护
  • Pro:通过网络传输的位更少(即只有过程名称和参数)
  • Pro:在数据库中编译
  • 优点:更好的安全性(用户不需要直接访问表)
  • 优点:出色的查询计划缓存(适合 OLTP查询——受益于计划重用)
  • 缺点:出色的查询计划缓存(不利于 OLAP查询——受益于独特的计划)
  • 缺点:让你与那个 SQL 供应商联系在一起

动态 SQL (即在存储过程中使用 exec 命令)

  • 优点:适用于简短的简单查询(又名 OLTP)
  • 优点:将数据库逻辑与业务逻辑分开
  • Pro:通过网络传输的位更少(即只有过程名称和参数)
  • Pro:允许引用任何表、数据库或列
  • Pro:允许基于参数添加/删除谓词(在 WHERE 子句中)
  • 优点:良好的查询计划缓存(对于 OLTP 和 OLAP 查询来说都是中等到好)
  • 缺点:只能编译proc的静态元素
  • 缺点:让你与那个 SQL 供应商联系在一起
  • 缺点:更难排除故障
  • 缺点:更容易受到 SQL 注入攻击

Ad Hoc SQL(即在您的业务代码中创建)

  • 优点:适合长时间、复杂的 quieres(又名 OLAP——即报告或分析)
  • 优点:灵活的数据访问
  • 优点:可以使用 ORM;可以在代码中编译/测试(即 Linq-to-Sql 或 SqlAlchemy)
  • 优点:查询计划缓存不佳(适合 OLAP查询——受益于独特的计划)
  • 缺点:查询计划缓存不佳(对 OLTP查询不利——受益于计划重用)
  • 缺点:通过网络传输更多位(即整个查询和参数)
  • 缺点:如果不使用 ORM,则更难维护
  • 缺点:如果不使用 ORM,则更难排除故障
  • 缺点:更容易受到 SQL 注入攻击

注意:始终参数化您的即席 SQL。

对于 OLAP ad hoc SQL:仅参数化字符串数据。这满足两个条件。它可以防止 SQL 注入攻击。它使查询看起来对数据库更加独特。是的,你会得到一个很差的查询计划缓存命中率。但这对于 OLAP 查询来说是可取的。他们受益于独特的计划生成,因为他们的数据集和最有效的计划在给定参数之间变化很大。

于 2010-05-29T10:33:59.980 回答
2

存储过程 PRO:

  • 编译。这意味着它的运行速度更快,并且对数据库服务器的 CPU 产生积极影响,因为它绕过了除首次执行之外的所有优化/编译阶段。
  • 允许对复杂的读写查询进行干净的权限控制。
  • 提供可重用的 API,允许一个良好的高效实现,而不是在各种平台上来自各种应用程序的一堆 Yahoos 重新实现 samke 查询并冒着获得低效实现的风险
  • 像任何 API 一样,提供抽象层。您可以更改底层实现(模式),而无需更改任何调用 SP 的代码。当所有平台上都有 100 多个使用该查询的应用程序时,这是一个非常大的优势。

存储过程缺点:

  • 与动态 SQL 相比,难以编写灵活的逻辑
  • 随着您的数据漂移和优化器选择的变化,具有预编译版本可能会导致执行效率降低。这很容易通过偶尔重新编译来改善。
于 2010-05-29T10:48:58.323 回答
0

关系型数据库?这个答案是特定于旧的 oracle

在旧的 oracle 版本 < 11 中,动态 sql 不会重用现有的 SGA sqltext 计划,它会为解析器需要的每个执行计划创建一个新条目。有很多动态 sql 调用,sqltext 区域被刷新得足够快,以至于查询重用下降了很多,性能也随之下降。

于 2010-05-29T14:39:41.980 回答
0

另一个优势是更容易“无停机升级”(对于重大升级,您仍然可能会导致一些停机时间)。

如果所有数据访问都是通过存储过程完成的,那么您可以轻松地将 v1 和 v2 的存储过程并排放置。

现在您可以让 v1 和 v2 的二进制文件/应用程序逻辑并行运行,每个都调用自己的存储过程版本。

通过 1、将 v1 应用程序锁定为只读模式(如果适用)、2、部署数据库更改,没有停机时间。3,重新启用对 v1 应用程序的正常访问,4,并排部署 v2 应用程序,告诉新用户使用新的二进制文件。6. 当没有更多用户使用旧的二进制文件时,关闭旧的二进制文件。

于 2012-08-02T15:50:26.803 回答
0

恕我直言,存储过程应该像瘟疫一样避免。以下是我不应该使用它们的十个很好的理由(适用于所有数据库):

  1. PL/SQL 语言适用于处理表、行和列中的数据。这是表达业务逻辑的糟糕选择。你可以用任何语言编写任何东西——这并不意味着你应该
  2. 大多数数据库缺乏一个体面的 IDE 来帮助处理语法和链接到其他现有程序(例如 Eclipse 为 java 做的)
  3. 很难找到编写和维护存储过程的人力资源——它们更稀有,因此也更昂贵
  4. 存储过程不能在数据库之间移植,因为 a) PL/SQL 没有行业标准 b) 即使有标准,您通常最终还是在存储过程中使用特定于数据库的功能/sql。如果您必须移动 dbs,您正在考虑完全重写您的业务逻辑
  5. 大多数数据库不提供对存储过程调试的任何支持——你只能在日志表中插入行或类似的东西来实现调试的日志记录——非常难看
  6. 要测试存储过程,您需要一个真实的数据库实例。这使得单元测试存储过程变得困难(您必须将它们部署到开发数据库才能运行它们)
  7. 要部署存储过程,您必须更新数据库(删除然后创建存储过程)。如果发现错误,您不能像使用应用程序代码那样简单地回滚到以前的二进制版本。相反,您必须找到旧代码,删除新的存储过程并(重新)创建旧的。这是改变之上的改变而不是回滚
  8. 您正在增加数据库服务器的处理需求,而不是将业务逻辑分发到其他(应用程序)服务器。由于数据库通常是单例的,这很糟糕,因为增加容量的唯一方法是购买更好的硬件(而不是购买更多的硬件或使用云)
  9. 它们并不使用准备好的语句编写的查询快得多,因为在数据库服务器上不断增加的处理需求和使用它们的效率之间需要权衡。除了速度不是一切(只要它是可以接受的):PL/SQL 的可维护性、可调试性、适用性等同样重要,甚至更重要
  10. 存储过程语言有有限的(如果有的话)库可以利用,所以你最终会写很多低价值的代码。这与应用程序语言不同,应用程序语言具有大量库,您可以将其用于业务逻辑所需的所有内容

只有一个地方我会批准它们的使用:对于非常特定的数据库功能 - 可能是密钥检查或数据类型转换或类似的东西,可能在触发器中,这非常重要,它证明了它的存在并且可能永远不会一写就改。

通常,您应该从存储过程中运行尖叫!

于 2013-01-25T09:20:34.343 回答
0

存储过程

  • 优点:无需在表级别授予更多基本权限即可授予操作许可。
  • 优点:离散且可版本化
  • Pro:允许您将架构与数据访问代码隔离开来。
  • 缺点:编写 CRUD 程序可能很乏味
  • 缺点:需要与底层架构保持一致

临时性和动态性 - 请参阅 Bill Paetzke 的回答和评论。

此外,不要忘记诸如 SQL 的批量插入之类的模式,这些模式不在您的列表中,但仍应予以考虑。

于 2010-05-29T10:47:09.917 回答