Хранимая процедура слишком медленная (с использованием CURSOR)

У меня есть код ниже, чтобы вставить необработанный (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 секунд)

Я держусь подальше от Query 1, потому что, если в базе данных произойдет сбой, это повлияет на записи. Примечание: я не могу использовать DISTRIBUTED TRANSACTION прямо сейчас, потому что это требует дополнительной настройки.

2 ответа

Вы пытались использовать аргумент FAST_FORWARD?

"FAT_FORWARD" определяет курсор FORWARD_ONLY, READ_ONLY с включенной оптимизацией производительности. FAST_FORWARD не может быть указан, если также указаны SCROLL или FOR_UPDATE.

Узнайте больше здесь.

Вы можете попробовать это: добавить дополнительный столбец в вашу таблицу, где вы добавили дополнительный флаг обработки. Сгенерируйте 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 и удалить флаг_обработки. Если что-то не получается, вы можете выбрать все непереданные строки, обработанные = 0 и processing_flag!= NULL.

У меня была похожая проблема с переносом отдельных строк. Объединяя их все в одну, моя проблема была решена.

Может быть, ваш целевой сервер или соединение слишком медленное.

Другие вопросы по тегам