【问题标题】:Stored Procedure is too slow (using CURSOR )存储过程太慢(使用 CURSOR )
【发布时间】:2018-02-20 21:47:27
【问题描述】:

我有以下代码将未处理的 (processed=0) 记录从服务器 1 插入到服务器 2(使用链接服务器),一旦插入,它应该更新为 processed=1

我只是在使用

查询 1:

INSERT INTO SELECT FROM WHERE processed=0
UPDATE processed=1 WHERE processed=0

查询 2:

DECLARE pending_records CURSOR LOCAL FOR
SELECT FROM WHERE processed=0

OPEN pending_records

FETCH NEXT FROM pending_records INTO @UniqueID

WHILE @@FETCH_STATUS=0
BEGIN

INSERT INTO SELECT FROM WHERE UniqueID=@UniqueID

IF @@ROWCOUNT=1 .... UPDATE processed=1 WHERE UniqueID=@UniqueID

FETCH NEXT FROM pending_records INTO @UniqueID

END

CLOSE pending_records

DEALLOCATE pending_records

查询 1 超级快,使用游标查询太慢(更新 1 条记录需要 30 秒)

我远离查询 1,因为如果数据库中有任何故障,它将影响记录。注意:我现在不能使用DISTRIBUTED TRANSACTION,因为它需要额外的设置。

【问题讨论】:

  • INSERT INTO SELECT FROM WHERE... 如果您担心我们仍会向您发送表名,可以自行编造。你至少可以做一个可以编译的示例。
  • @ZoharPeled 我可以。我现在只注意到一件事,没有IF @@ROWCOUNT=1 .... UPDATE processed=1 WHERE UniqueID=@UniqueID,完成 400 条记录只需 3 秒。使用更新命令,大约需要 15 分钟(400 条记录)
  • 所以请edit您的问题,以便我们可以看到有意义的代码。此外,如果我们知道什么表在什么服务器上可能会有所帮助。
  • @ZoharPeled 或者我可以使用WHILE (count(*) from table > 0), Update top 1....
  • 为什么要使用游标来进行这些更新?您不想在这里使用光标,因为您发现性能很糟糕。如果您只想捕获那些已处理的内容,您应该在插入语句中使用输出子句到临时表,然后在插入语句中使用该临时表。

标签: sql sql-server sql-server-2005 cursor linked-server


【解决方案1】:

你可以试试这个:在你的表中添加一个额外的列,你可以在其中放置一个额外的处理标志。在存储过程开始时生成 GUID 并更新表:

UPDATE <table>
SET processing_flag = <GUID>
WHERE processed = 0;

然后您可以通过

简单地将您的行传输到另一台服务器
INSERT INTO <target>
SELECT <columns>
FROM <source>
WHERE processed = 0 AND processing_flag = <GUID>;

在此之后,您可以设置已处理 = 1 并擦除 processing_flag。如果发生故障,您可以通过处理 = 0 和 processing_flag != NULL 选择所有未传输的行。

我在传输单行时遇到了类似的问题。把它们合二为一,我的问题就解决了。

也许你的目标服务器或者连接太慢了。

【讨论】:

  • 我不能修改表格,它被第三方应用程序使用了。
  • 可以添加新表吗?
  • 处理什么样的数据类型?
  • 测试是 varchar(10),实时是日期。 unprocessed 将是 NULLprocessed 将带有日期
  • 让我问一个问题:为什么你不能修改表,因为它被第 3 方应用程序使用,然后你写它来测试它的 varchar(10) 和 live date?
【解决方案2】:

您是否尝试过使用“FAST_FORWARD”参数?

“FAT_FORWARD”指定启用了性能优化的 FORWARD_ONLY、READ_ONLY 游标。如果同时指定了 SCROLL 或 FOR_UPDATE,则不能指定 FAST_FORWARD。

阅读更多here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    相关资源
    最近更新 更多