В чем преимущество использования FAST_FORWARD для определения курсора? - PullRequest
18 голосов
/ 17 февраля 2010

В чем преимущество использования FAST_FORWARD для определения курсора?Это лучше для производительности?почему?

Ответы [ 5 ]

18 голосов
/ 17 февраля 2010

Определение от MSDN :

Указывает FORWARD_ONLY, READ_ONLY курсор с оптимизацией производительности включено . FAST_FORWARD не может быть указывается, если SCROLL или FOR_UPDATE также указано. FAST_FORWARD и FORWARD_ONLY являются взаимоисключающими; если один указан, другой не может быть уточненным.

Я немного смелее. Он может поддерживать эти «оптимизации производительности», поскольку ему не требуется поддержка многоходовой итерации через курсор (FORWARD_ONLY) и не поддерживается изменение (READ_ONLY).

Конечно, если вам вообще не нужно использовать курсор - тогда использование курсора даже с этой опцией также не будет работать. Если вы можете выполнить ту же задачу, используя подход, основанный на множестве, сделайте это вместо этого - это то, что я действительно хотел подчеркнуть.

8 голосов
/ 17 февраля 2010

FAST_FORWARD - указывает, что курсор будет курсором FORWARD_ONLY и READ_ONLY. Курсоры FAST_FORWARD создают наименьшую нагрузку на SQL Server.

Источник: Нажмите здесь

4 голосов
/ 17 февраля 2010

FAST_FORWARD указывает, что это FORWARD_ONLY и READ_ONLY, что означает, что он использует наименьшее количество ресурсов сервера для его обработки ... так что да, для производительности.

MSDN имеет полный список опций курсора здесь .

FAST_FORWARD

  • Указывает курсор FORWARD_ONLY, READ_ONLY с включенной оптимизацией производительности. FAST_FORWARD не может быть указан, если также указаны SCROLL или FOR_UPDATE.
3 голосов
/ 22 сентября 2014

(я знаю, что это старо, но для потомков)

Просто для расширения курсоров "fast_forward" и "forward_only / read_only" разница заключается в использовании плана курсора.

FO/RO курсоры всегда используют динамический план запроса - и для большинства приложений этого достаточно. Однако даже хороший динамический план почти никогда не бывает таким же хорошим, как статический план.

FF курсоры будут использовать статический план, если он лучше, и никогда не будут понижать планы курсора (в основном это относится к "... с включенной оптимизацией производительности.")

Как правило, динамические планы более оптимальны для курсоров с небольшим набором результатов (с низким уровнем цели) и наоборот для статических.

2 голосов
/ 08 декабря 2014

Просто помните, что FAST_FORWARD ДИНАМИЧНЫЙ ... 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...