【问题标题】:Which is faster in SQL, While loop, Recursive Stored proc, or Cursor?SQL、While 循环、递归存储过程或游标中哪个更快?
【发布时间】:2011-03-02 15:58:49
【问题描述】:

在 SQL、While 循环、递归存储过程或游标中哪个更快? 我想优化存储过程中几个位置的性能。 我正在优化的代码格式化了一些字符串以输出到文件。

【问题讨论】:

  • 这可能取决于您使用的数据库...
  • 取决于里面的内容。 cursor 是沿行移动的方式,While 是控制结构。忘记递归,堆栈深度限制为 32。
  • 我正在从 sql 输出到文件。我不知道有一种面向集合的方式来做到这一点。
  • 哪个版本的 SQL - Oracle、SQLServer、MYSQL、Postgres 等?
  • 通过递归,您可以达到最大递归级别。如果我记得,对于 Sql Server,这就像 32 次最大递归。

标签: sql-server performance stored-procedures while-loop database-cursor


【解决方案1】:

D) 以上都不是。

基于集合的方法几乎总是最快的方法。在不知道您的实际代码是什么(或近似值)的情况下,很难说这是否可行或哪种方法最快。

最好的办法是测试所有可能的方法,看看哪种方法真正最快。

【讨论】:

  • 我必须输出到一个文本文件。我不知道如何输出,除了迭代,因为我必须在输出到文件之前格式化字段。
  • 使用bcp和queryout,在查询中做格式化,这里假设sql server,大部分rdbms都有类似的东西
【解决方案2】:

如果你想提高性能,那么你需要看看基于 SET 的操作,While 循环和游标基本上是一回事。 SQL 在 SET 中工作,它不是一种过程语言,请按预期使用它

【讨论】:

    【解决方案3】:

    递归存储过程可能最慢,而循环和游标不是互斥的。游标操作非常快(IME),但我只在外部(非 SQL)代码中使用过它们。其他海报是正确的,如果您可以以面向集合的方式进行处理,您将获得最佳性能。

    【讨论】:

    • 这可能是唯一真正回答了所提问题的帖子,并且在大多数情况下都正确。按照性能顺序,它将是:1. 快进光标(大多数光标可以是 FF),2. While 循环,3. 递归 SP。 (在这个规模上,Set Ops 将是 0。)
    【解决方案4】:

    我假设您使用的是 SQL Server。

    首先,正如有人在语句中所说,递归存储过程虽然可能,但由于堆栈大小,在 SQL Server 中并不是一个好主意。因此,任何深度递归逻辑都会中断。 但是,如果您最多有 2-3 级嵌套,您可以尝试使用递归或使用CTE,这也有点递归(SQL Server 2005 及更高版本)。一旦你设法围绕 CTE 进行思考,它就是一种非常有用的技术。 我没有测量过,但在我使用 CTE 的少数几个地方我从来没有遇到过性能问题。

    另一方面,游标会消耗大量性能,因此我 (and half the internet) 建议不要在经常调用的代码中使用它们。但是由于游标更像是一种经典的编程结构,类似于 C# 中的 foreach,因此有些人发现使用游标进行数据操作的 SQL 代码比一些复杂的多内选 SQL 怪物更容易查看、理解和维护,因此在不时调用的代码中使用它们并不是最糟糕的主意。

    说到while,它也将编程思维从基于集合的思维转变为基于过程的思维方式,因此虽然速度相对较快且不消耗大量资源,但仍然可以大幅增加数据量您向数据库本身发出的操作语句。

    总而言之,如果我必须制作一个性能至关重要的复杂存储过程,我会尝试:

    1. 使用基于集合的方法(内部选择、连接、联合等)
    2. 使用 CTE(对于有经验的用户来说清晰且易于管理,对于初学者来说有点阴暗)
    3. 使用控制流语句(if、while...)
    4. 使用游标(程序代码,易于理解)

    按这个顺序。

    如果代码的使用频率低得多,我可能会将 3 和 4 移到 1 和 2 之前,但同样,仅适用于使用大量表和大量关系的复杂场景。当然,YMMV,所以我会测试我在真实场景中所做的任何程序,以实际测量性能,因为,我们可以谈论直到我们脸色发青,这很快,那很慢,但直到你得到了真正的测量结果,没有办法判断变化是使事情变得更好还是更糟。

    而且,不要忘记,代码的速度与您的数据一样快。良好的索引是无可替代的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-13
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 2012-06-23
      • 2010-12-08
      • 1970-01-01
      • 2016-06-03
      相关资源
      最近更新 更多