【问题标题】:Ad hoc queries vs stored procedures vs Dynamic SQL [closed]即席查询与存储过程与动态 SQL [关闭]
【发布时间】:2011-02-25 10:50:41
【问题描述】:

即席查询与存储过程与动态 SQL。谁能说说利弊?

【问题讨论】:

    标签: sql stored-procedures dynamic-sql adhoc-queries


    【解决方案1】:

    恕我直言,存储过程应该像瘟疫一样被避免。这里有十个很好的理由来说明为什么你永远不应该使用它们(适用于所有数据库):

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

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

    一般来说,您应该从存储过程中运行尖叫!

    【讨论】:

    • 难以置信的错误!!!
    • @Fred 我去过那里 - 我已经构建了几个基于存储过程的生产服务器。经验告诉我,这是绝对正确的。由于所有这些原因以及更多原因,存储过程完全是垃圾!您究竟不同意哪些观点?
    • 我相信您在这里所说的大部分内容都可以争论,但不会有太多时间争论的是:(2) MS SQL Server Management Studio 提供的 IDE 对 IMO 非常有用. (3) 在英国,优秀的数据库开发人员并不难找到。 (7) 您不必删除和创建数据库来部署存储过程。存储过程可以帮助源代码控制,就像应用程序代码一样。如果您发现错误,您可以非常简单地回滚到以前的版本。如果您使用 AD Hoc SQL,则必须重新部署整个应用程序来修复 SQL 错误而不是一个存储过程
    • 我想这完全是个人喜好问题,但您在这里提出的一些论点实际上是不正确的。
    • 你忘了提到参数嗅探问题,这是存储过程中最常见的问题,很难调优,大多数时候根本没有灵丹妙药,同样计划的问题是你总是有相同的计划。有时,结果集可能会根据参数的值而有很大差异。动态查询根本没有这些问题
    【解决方案2】:

    存储过程

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

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

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

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

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

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

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

    【讨论】:

    • +1 另外,我将添加对网络流量的列表效果,计划缓存。
    • @Martin -- 我刚刚添加了网络和计划缓存信息。感谢您的建议。
    • 另外一个 big 用于存储过程:您的用户不需要直接访问表!在安全性(和安全性)方面的巨大优势
    • 我很确定您的意思是“通过网络传输更多位”是 Ad Hoc SQL 的一个骗局。 (虽然,使用 OLAP,您希望处理较大的数据集,其中传输到服务器的数据大小是微不足道的。)
    • @marc_s:在数据库端实现所有安全性固然不错,但它也将您与数据库供应商的联系更加紧密。如果您有一个单独的数据层,您可以在那里实现您的安全性,然后设置数据库,使其只接受数据层用户的写入。您可能会发现一些关于为什么在数据库上执行此操作更安全的论据,但我不确定您做出的牺牲是否值得。
    【解决方案3】:

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

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

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

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

    【讨论】:

      【解决方案4】:

      关系数据库管理系统?此答案特定于旧版 oracle

      在旧的 oracle 版本

      【讨论】:

        【解决方案5】:

        存储过程 PRO:

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

        存储过程的缺点:

        • 与动态 SQL 相比,难以编写灵活的逻辑
        • 随着数据漂移和优化器选择的变化,预编译版本会导致执行效率降低。这很容易通过偶尔重新编译来改善。

        【讨论】:

          【解决方案6】:

          存储过程

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

          临时和动态 - 请参阅 Bill Paetzke 的答案和 cmets。

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-10-18
            • 2013-09-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-12
            • 1970-01-01
            相关资源
            最近更新 更多