web-dev-qa-db-ja.com

カーソルを定義するためにFAST_FORWARDを使用する利点は何ですか?

カーソルを定義するためにFAST_FORWARDを使用する利点は何ですか?パフォーマンスに優れていますか?どうして?

20
masoud ramezani

[〜#〜] msdn [〜#〜] からの定義は次のとおりです。

パフォーマンスの最適化が有効になっているFORWARD_ONLY、READ_ONLYカーソルを指定します。 SCROLLまたはFOR_UPDATEも指定されている場合、FAST_FORWARDは指定できません。 FAST_FORWARDとFORWARD_ONLYは相互に排他的です。一方が指定されている場合、もう一方は指定できません。

キービットを太字にしました。カーソルを介した多方向の反復(FORWARD_ONLY)をサポートする必要がなく、変更(READ_ONLY)をサポートしないため、これらの「パフォーマンスの最適化」をサポートできます。

もちろん、実際にカーソルを使用する必要がまったくない場合は、このオプションを使用してもカーソルを使用してもパフォーマンスは低下します。セットベースのアプローチを使用して同じタスクを実行できる場合は、代わりにそれを実行してください。これは、私が本当に強調したかったビットです。

19
AdaTheDev

FAST_FORWARD-カーソルがFORWARD_ONLYおよびREAD_ONLYカーソルになることを指定します。 FAST_FORWARDカーソルは、SQLServerで発生するオーバーヘッドを最小限に抑えます。

出典: ここをクリック

8
Adeel

FAST_FORWARDは、それがFORWARD_ONLYおよびREAD_ONLYであることを指定します。つまり、パフォーマンスのために、サーバーリソースの使用量が最小であることを意味します。

MSDNにはここにカーソルオプションの完全な要約があります

FAST_FORWARD

  • パフォーマンスの最適化が有効になっているFORWARD_ONLY、READ_ONLYカーソルを指定します。 SCROLLまたはFOR_UPDATEも指定されている場合、FAST_FORWARDは指定できません。
4
Nick Craver

(私はこれが古いことを知っていますが、後世のために)

「fast_forward」カーソルと「forward_only/read_only」カーソルを詳しく説明するために、違いはカーソルプランの使用法にあります。

FO/ROカーソルは常に動的クエリプランを使用します。ほとんどのアプリケーションでは、これで十分です。ただし、優れた動的計画でさえ、静的計画ほど優れていることはほとんどありません。

FFカーソルは、より適切な場合は静的プランを使用し、カーソルプランをダウングレードすることはありません(主に「...パフォーマンスの最適化が有効になっている」が参照しているもの)。

一般に、動的プランは小さな結果セット(「低目標」)カーソルに最適であり、静的プランにはその逆が最適です。

3
George Moran

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