使用FAST_FORWARD定义游标有什么好处?

时间:2010-02-17 12:18:42

标签: sql sql-server cursor

使用FAST_FORWARD定义游标有什么好处?性能更好吗?为什么呢?

5 个答案:

答案 0 :(得分:17)

MSDN的定义是:

  

指定FORWARD_ONLY,READ_ONLY   光标具有性能优化   启用即可。 FAST_FORWARD不能   指定SCROLL或FOR_UPDATE是否为   也指定。 FAST_FORWARD和   FORWARD_ONLY是相互排斥的;   如果指定了另一个则不能   指定。

我把关键位加了下来。它可以支持这些“性能优化”,因为它不需要支持通过游标进行多方向迭代(FORWARD_ONLY),也不支持修改(READ_ONLY)。

当然,如果您根本不需要使用光标 - 那么即使使用此选项也不会使用光标。如果您可以使用基于集合的方法执行相同的任务,请执行此操作 - 这是我真正想要强调的一点。

答案 1 :(得分:8)

FAST_FORWARD - 指定游标将为FORWARD_ONLY和READ_ONLY游标。 FAST_FORWARD游标在SQL Server上产生的开销最小。

来源:Click Here

答案 2 :(得分:4)

FAST_FORWARD指定它是FORWARD_ONLYREAD_ONLY,这意味着它使用最少量的服务器资源来处理它...所以是的,为了性能。

MSDN has a full rundown of cursor options here

  

<强> FAST_FORWARD

     
      
  • 指定启用了性能优化的FORWARD_ONLY,READ_ONLY游标。如果还指定了SCROLL或FOR_UPDATE,则无法指定FAST_FORWARD。
  •   

答案 3 :(得分:3)

(我知道这是旧的,但后人)

只是为了阐述&#34; fast_forward&#34;和&#34; forward_only / read_only&#34;游标,区别在于游标计划的使用。

FO/RO游标总是使用动态查询计划 - 对于大多数应用程序来说,这就足够了。 然而,即使是一个好的动态计划也几乎没有静态计划那么好。

FF游标会使用静态计划,如果它更好,并且不会降级游标计划(主要是&#34; ...启用了性能优化。&# 34;指的是。)

通常,动态计划对于小结果集(&#34;低目标&#34;)游标更为理想,反之亦然。

答案 4 :(得分:2)

请记住,FAST_FORWARD是DYNAMIC ... FORWARD_ONLY你可以使用STATIC游标。

尝试在万圣节问题上使用它,看看会发生什么!!!

IF OBJECT_ID('Funcionarios') IS NOT NULL
DROP TABLE Funcionarios
GO

CREATE TABLE Funcionarios(ID          Int IDENTITY(1,1) PRIMARY KEY,
                          ContactName Char(7000),
                          Salario     Numeric(18,2));
GO

INSERT INTO Funcionarios(ContactName, Salario) VALUES('Fabiano', 1900)
INSERT INTO Funcionarios(ContactName, Salario) VALUES('Luciano',2050)
INSERT INTO Funcionarios(ContactName, Salario) VALUES('Gilberto', 2070)
INSERT INTO Funcionarios(ContactName, Salario) VALUES('Ivan', 2090)
GO

CREATE NONCLUSTERED INDEX ix_Salario ON Funcionarios(Salario)
GO

-- Halloween problem, will update all rows until then reach 3000 !!!
UPDATE Funcionarios SET Salario = Salario * 1.1
  FROM Funcionarios WITH(index=ix_Salario)
 WHERE Salario < 3000
GO

-- Simulate here with all different CURSOR declarations
-- DYNAMIC update the rows until all of then reach 3000
-- FAST_FORWARD update the rows until all of then reach 3000
-- STATIC update the rows only one time. 

BEGIN TRAN
DECLARE @ID INT
DECLARE TMP_Cursor CURSOR DYNAMIC 
--DECLARE TMP_Cursor CURSOR FAST_FORWARD
--DECLARE TMP_Cursor CURSOR STATIC READ_ONLY FORWARD_ONLY
    FOR SELECT ID 
          FROM Funcionarios WITH(index=ix_Salario)
         WHERE Salario < 3000

OPEN TMP_Cursor

FETCH NEXT FROM TMP_Cursor INTO @ID

WHILE @@FETCH_STATUS = 0
BEGIN
  SELECT * FROM Funcionarios WITH(index=ix_Salario)

  UPDATE Funcionarios SET Salario = Salario * 1.1 
   WHERE ID = @ID

  FETCH NEXT FROM TMP_Cursor INTO @ID
END

CLOSE TMP_Cursor
DEALLOCATE TMP_Cursor

SELECT * FROM Funcionarios

ROLLBACK TRAN
GO