【问题标题】:What is the advantage of using FAST_FORWARD for defining a cursor?使用 FAST_FORWARD 定义游标有什么好处?
【发布时间】:2011-01-17 20:05:13
【问题描述】:

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

【问题讨论】:

    标签: sql sql-server database-cursor


    【解决方案1】:

    请记住,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
    

    【讨论】:

    • FAST_FORWARD 并不总是动态的。如果 STATIC 是一个更好的计划,它将切换到 STATIC。
    • @Ahmed 是的,但 FORWARD_ONLY STATIC 保证是静态的,而 FAST_FORWARD 则不受您的控制
    【解决方案2】:

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

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

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

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

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

    【讨论】:

      【解决方案3】:

      来自MSDN的定义是:

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

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

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

      【讨论】:

        【解决方案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。

        【讨论】:

          【解决方案5】:

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

          来源:Click Here

          【讨论】:

            猜你喜欢
            • 2011-04-21
            • 1970-01-01
            • 2011-09-08
            • 2012-04-28
            • 2023-02-10
            • 2010-12-16
            • 2011-09-25
            • 1970-01-01
            相关资源
            最近更新 更多