24

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

4

5 回答 5

20

MSDN的定义是:

指定启用了性能优化的 FORWARD_ONLY、READ_ONLY 游标。如果同时指定了 SCROLL 或 FOR_UPDATE,则无法指定 FAST_FORWARD。FAST_FORWARD 和 FORWARD_ONLY 是互斥的;如果指定了一个,则无法指定另一个。

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

当然,如果您根本不需要使用游标,那么即使使用此选项也不会使用游标。如果您可以使用基于集合的方法来完成相同的任务,请改为这样做 - 这是我真正想强调的一点。

于 2010-02-17T12:27:26.333 回答
13

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

来源:点击这里

于 2010-02-17T12:22:34.693 回答
4

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

MSDN 在此处提供了光标选项的完整概要

FAST_FORWARD

  • 指定启用了性能优化的 FORWARD_ONLY、READ_ONLY 游标。如果同时指定了 SCROLL 或 FOR_UPDATE,则无法指定 FAST_FORWARD。
于 2010-02-17T12:23:31.497 回答
3

请记住,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
于 2014-12-08T13:26:07.397 回答
2

(我知道这是旧的,但为了后代)

只是为了说明“fast_forward”和“forward_only/read_only”游标,区别在于游标计划的使用。

FO/RO游标总是使用动态查询计划——对于大多数应用程序来说,这已经足够了。然而,即使是好的动态计划也几乎永远不会像静态计划那样好。

FF如果更好,游标将使用静态计划,并且永远不会降级游标计划(主要是“...启用性能优化。”指的是)。

一般来说,动态计划更适合小结果集(“低目标”)游标,反之亦然。

于 2014-09-22T15:00:14.190 回答