カーソルの定義に FAST_FORWARD を使用する利点は何ですか? パフォーマンスの方が良いですか?なぜ?
5 に答える
MSDNからの定義は次のとおりです。
パフォーマンスの最適化が有効なFORWARD_ONLY、READ_ONLY カーソルを指定します。SCROLLまたはFOR_UPDATEも指定されている場合、FAST_FORWARDは指定できません。FAST_FORWARD と FORWARD_ONLY は相互に排他的です。一方が指定されている場合、もう一方は指定できません。
キービットを太字にしました。カーソルを介した多方向反復をサポートする必要がなく (FORWARD_ONLY)、変更をサポートしない (READ_ONLY) ため、これらの「パフォーマンスの最適化」をサポートできます。
もちろん、カーソルをまったく使用する必要がない場合は、このオプションを使用してもカーソルを使用してもパフォーマンスは向上しません。セットベースのアプローチを使用して同じタスクを実行できる場合は、代わりにそれを実行してください。これは、私が本当に強調したかった点です。
FAST_FORWARD - カーソルが FORWARD_ONLY および READ_ONLY カーソルになることを指定します。FAST_FORWARD カーソルは、SQL Server のオーバーヘッドを最小限に抑えます。
出典:ここをクリック
はそれがandでFAST_FORWARD
あることを指定します。つまり、それを処理するために最小限のサーバー リソースを使用することを意味します...そうです、パフォーマンスのために。FORWARD_ONLY
READ_ONLY
MSDN には、カーソル オプションの完全な概要が記載されています。
早送り
- パフォーマンスの最適化が有効な FORWARD_ONLY、READ_ONLY カーソルを指定します。SCROLLまたはFOR_UPDATEも指定されている場合、FAST_FORWARDは指定できません。
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」カーソルと「forward_only/read_only」カーソルを詳しく説明すると、違いはカーソル プランの使用方法にあります。
FO/RO
カーソルは常に動的クエリ プランを使用します。ほとんどのアプリケーションでは、これで十分です。ただし、優れた動的計画でさえ、静的計画ほど優れていることはほとんどありません。
FF
カーソルは、より良い場合は静的プランを使用し、カーソルプランをダウングレードすることはありません (ほとんどの場合、「...パフォーマンスの最適化が有効になっている」が参照しています)。
一般に、動的プランは小さな結果セット (「低目標」) カーソルに最適であり、静的プランにはその逆が適しています。