存储过程太慢(使用CURSOR)

时间:2017-09-12 12:20:58

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

我有以下代码将未处理的(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,因为它需要额外的设置。

2 个答案:

答案 0 :(得分:1)

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

'FAT_FORWARD'指定启用了性能优化的FORWARD_ONLY,READ_ONLY游标。如果还指定了SCROLL或FOR_UPDATE,则无法指定FAST_FORWARD。

了解更多here

答案 1 :(得分:0)

You could try this: add an extra column to your table where you put an extra processing-flag. Generate a GUID at the beginning of your stored procedure and update your table:

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

And then you can simply transfer your rows to the other server by

INSERT INTO <target>
SELECT <columns>
FROM <source>
WHERE processed = 0 AND processing_flag = <GUID>;

After this you can set processed = 1 and erase the processing_flag. If something Fails you can select all not transfered rows by processed = 0 and processing_flag != NULL.

I had a similar problem with transfering single rows. By putting them all in one my problem was solved.

Maybe your target-server or the connection is too slow too.