TSQL CURSOR和基于SET的替代方案

时间:2014-09-16 11:03:10

标签: tsql sql-server-2008-r2 cursor

我已经在许多地方读过,用基于集合的替代方案替换CURSOR会大大提高性能但是我还没有找到一个示例,教程,解释基于集合的替代方案实际上是什么以及光标如何被转换成一个。

任何人都可以提供任何链接吗?

由于

1 个答案:

答案 0 :(得分:1)

转到RDBMS中的Relational,你会看到MSSQL,Oracle和其他系统都经过优化,可以使用集合。游标更像是C#等命令式过程语言。

对于一个小例子,尝试实现连接!您可以使用游标来执行嵌套循环来模仿连接。 愚蠢的例子肯定,但你明白了。连接可能比光标快。

另外请注意,表现不仅仅是最好的方式。它是关于使用更少的资源。这些资源是: CPU,内存,IO,HD,用户耐心(时间)。游标可以消耗所有资源。

有时可以使用FAST FORWARD和其他技巧来优化游标。最后,光标可以是一个选项,甚至是工作的最佳工具(它们存在于动机中)。

游标的问题是它们被缺乏基于集合体验的开发人员过度使用。那些家伙试图将这种类似C的编程风格应用于关系世界,并带来可怕的结果。

修改 这是一个借鉴SQL Shack

的例子
DECLARE @rowguidVar UNIQUEIDENTIFIER  -- prepare unique ID variable to use in the WHERE statement below

DECLARE test_cursor CURSOR FOR  
SELECT rowguid
FROM   AdventureWorks2012.Sales.SalesOrderDetail
WHERE  ModifiedDate BETWEEN '2008-07-15 00:00:00.000' AND '2008-07-31 00:00:00.000'

OPEN test_cursor  
FETCH NEXT FROM test_cursor INTO @rowguidVar  
--This is the start of the cursor loop.
WHILE @@FETCH_STATUS = 0  
BEGIN  
       SELECT *
          FROM            Sales.SalesOrderDetail
          WHERE    rowguid = @rowguidVar
   FETCH NEXT FROM test_cursor INTO @rowguidVar  
END

CLOSE test_cursor  
DEALLOCATE test_cursor
-- Don't forget these statements which flush the cursor from memory

相同
SELECT  *
FROM    AdventureWorks2012.Sales.SalesOrderDetail
WHERE   ModifiedDate BETWEEN '2008-07-15 00:00:00.000' AND '2008-07-31 00:00:00.000'