【问题标题】:TSQL CURSOR and SET Based Alternatives基于 TSQL CURSOR 和 SET 的替代方案
【发布时间】:2014-11-10 02:28:00
【问题描述】:

我在很多地方都读到,用基于集合的替代方案替换 CURSOR 可以显着提高性能,但我还没有找到示例、教程、解释基于集合的替代方案实际上是什么以及游标如何转换成一个。

谁能提供这样的链接?

谢谢

【问题讨论】:

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


【解决方案1】:

使用 RDBMS 中的关系,您会发现 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'

【讨论】:

    猜你喜欢
    • 2013-09-21
    • 1970-01-01
    • 2011-07-15
    • 2010-11-07
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    • 2010-09-10
    • 1970-01-01
    相关资源
    最近更新 更多