Sql server SQL、While循环、递归存储过程或游标中哪个更快?

Sql server SQL、While循环、递归存储过程或游标中哪个更快?,sql-server,performance,stored-procedures,while-loop,cursor,Sql Server,Performance,Stored Procedures,While Loop,Cursor,SQL、While循环、递归存储过程或游标中哪个更快? 我想优化存储过程中几个点的性能。 我正在优化的代码将一些字符串格式化,以便输出到文件。D以上都没有 基于集合的方法几乎总是最快的方法。如果不知道实际代码是什么或近似值,很难说这是否可能,或者哪种方法最快 最好的办法是测试所有可能的方法,看看哪种方法最快。如果你想提高性能,那么你需要看看基于集合的操作,而循环和游标基本上是一样的。SQL在集合中工作,它不是一种过程语言,按预期的方式使用它递归存储过程可能是最慢的,而循环和游标不是互斥的。游标操

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

D以上都没有

基于集合的方法几乎总是最快的方法。如果不知道实际代码是什么或近似值,很难说这是否可能,或者哪种方法最快


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

如果你想提高性能,那么你需要看看基于集合的操作,而循环和游标基本上是一样的。SQL在集合中工作,它不是一种过程语言,按预期的方式使用它递归存储过程可能是最慢的,而循环和游标不是互斥的。游标操作非常快,但我只在外部非SQL代码中使用过它们。其他海报都是正确的,如果你能以一种面向集合的方式进行处理,你将获得最佳性能。

你还不知道,但你想读这本书


我假设您使用的是SQL Server

首先,正如有人在语句中所说,递归存储过程虽然可能,但由于堆栈的大小,在SQL Server中不是一个好主意。因此,任何深度递归逻辑都将被打破。 但是,如果您最多有2-3个嵌套级别,您可以尝试使用递归或使用,这也是一种递归SQLServer2005及更高版本。一旦你成功地将你的头缠绕在CTE上,这将是一项非常有用的技术。 我没有测量过,但在我使用CTE的几个地方,我从未遇到过性能问题

另一方面,游标对性能影响很大,所以我建议不要在经常调用的代码中使用它们。但是,由于游标更像是一种经典的编程结构,类似于C中的foreach,一些人发现在复杂的多个内部选择SQL怪物上,更容易查看、理解和维护使用游标进行数据操作的SQL代码,因此在偶尔调用的代码中使用游标并不是最糟糕的主意

说到while,它还将编程思维从基于集合的思维转移到基于过程的思维,因此虽然它相对较快且不消耗大量资源,但仍然可以显著增加向数据库本身发出的数据操作语句的数量

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

使用基于集合的方法进行内部选择、联接、并集等 对于有经验的用户来说,使用CTE是清晰且易于管理的,对于初学者来说,这有点不太靠谱 在以下情况下使用控制流语句:。。。 使用游标的程序代码,简单易懂 按这个顺序

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


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

有一篇关于游标的三部分博客文章,如果你有时间的话,值得一读。我也像躲避瘟疫一样躲避它们,但这个博客让我从不同的角度看待它们。。。好我现在稍微弄脏了一点,但还是不会用


看看哪一个会给你一些关于如何用基于集合的操作替换游标的想法

这可能取决于你使用的是哪一个数据库…取决于它里面有什么。光标是沿着行移动的方式,而控件是结构。忘记递归吧,堆栈深度受32限制。我正在从sql输出到一个文件。我不知道有什么面向集合的方法可以做到这一点。哪个版本的SQL-Oracle、SQLServer、MYSQL、Postgres等?使用递归,可以达到最大的递归级别。如果我记得的话,对于Sql Server,这就像是32个最大递归。我必须输出到一个文本文件。我不知道除了迭代外如何输出,因为我必须在输出到文件之前格式化字段。使用bcp和queryyout,在查询中进行格式化,这假设sql server,大多数rdbms都有类似的内容。这可能是唯一一篇真正回答问题的帖子,并且在大多数情况下都是正确的。按照性能的顺序,应该是:1。快进光标大多数光标可以是FF,2。而循环,3。递归SP.和Set Ops在该刻度上为0。