使用 FAST_FORWARD 定义游标有什么好处?

发布于 2024-08-22 01:35:07 字数 43 浏览 8 评论 0原文

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

What is the advantage of using FAST_FORWARD for defining a cursor? Is it better for performance? why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

兲鉂ぱ嘚淚 2024-08-29 01:35:07

MSDN 中的定义是:

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

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

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

The definition from MSDN is:

Specifies a FORWARD_ONLY, READ_ONLY
cursor with performance optimizations
enabled
. FAST_FORWARD cannot be
specified if SCROLL or FOR_UPDATE is
also specified. FAST_FORWARD and
FORWARD_ONLY are mutually exclusive;
if one is specified the other cannot
be specified.

I've boldened the key bit. It can support these "performance optimisations" because it does not need to support multi-direction iterating through the cursor (FORWARD_ONLY) and does not support modifications (READ_ONLY).

Of course, if you don't really need to use a cursor at all - then using a cursor even with this option is not going to perform as well . If you can do the same task using a set-based approach, do that instead - this is the bit I really wanted to stress.

惜醉颜 2024-08-29 01:35:07

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

来源:点击此处

FAST_FORWARD - specifies that cursor will be FORWARD_ONLY and READ_ONLY cursor. The FAST_FORWARD cursors produce the least amount of overhead on SQL Server.

Source: Click Here

可遇━不可求 2024-08-29 01:35:07

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

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

FAST_FORWARD

  • 指定启用性能优化的 FORWARD_ONLY、READ_ONLY 游标。如果同时指定了 SCROLL 或 FOR_UPDATE,则无法指定 FAST_FORWARD。

The FAST_FORWARD specifies that it's FORWARD_ONLY and READ_ONLY, meaning it uses the least amount of server resources to handle it...so yes, for performance.

MSDN has a full rundown of cursor options here.

FAST_FORWARD

  • Specifies a FORWARD_ONLY, READ_ONLY cursor with performance optimizations enabled. FAST_FORWARD cannot be specified if SCROLL or FOR_UPDATE is also specified.
長街聽風 2024-08-29 01:35:07

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

Just keep in mind that FAST_FORWARD is DYNAMIC ... FORWARD_ONLY you can use with a STATIC cursor.

Try using it on the Halloween problem to see what happens !!!

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
握住我的手 2024-08-29 01:35:07

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

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

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

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

一般来说,动态计划对于小结果集(“低目标”)游标来说更为优化,对于静态游标反之亦然。

(I know this is old, but for posterity)

Just to expatiate the "fast_forward" and "forward_only/read_only" cursors, the difference is in cursor plan usage.

FO/RO cursors always use a dynamic query plan - and for most applications, this is sufficient.
However, even a good dynamic plan is almost never as good as a static plan.

FF cursors will use a static plan if it's better, and won't ever downgrade cursor plans (mostly what the "...with performance optimizations enabled." is referring to).

Generally dynamic plans are more optimal for small result set ("low-goal") cursors, and vice-versa for static.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文