Я пишу процедуры DB2 всего несколько дней, но пытаюсь выполнить "пакетное удаление" для данной таблицы. Моя ожидаемая логика:
- открыть курсор
- пройти через него до EOF
- выдавать DELETE на каждой итерации
Для упрощения этого вопроса предположим, что я хочу выполнить только один COMMIT (из всех DELETE) после завершения цикла WHILE (т.е. после того, как курсор достигнет EOF). Итак, учитывая пример кода ниже:
CREATE TABLE tableA (colA INTEGER, ...)
CREATE PROCEDURE "SCHEMA"."PURGE_PROC"
(IN batchSize INTEGER)
LANGUAGE SQL
SPECIFIC SQL140207163731500
BEGIN
DECLARE tempID INTEGER;
DECLARE eof_bool INTEGER DEFAULT 0;
DECLARE sqlString VARCHAR(1000);
DECLARE sqlStmt STATEMENT;
DECLARE myCurs CURSOR WITH HOLD FOR sqlStmt;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET eof_bool = 1;
SET sqlString = 'select colA from TableA';
PREPARE sqlStmt FROM sqlString;
OPEN myCurs;
FETCH myCurs INTO tempID;
WHILE (eof_bool = 0) DO
DELETE FROM TableA where colA = tempID;
FETCH myCurs INTO tempID;
END WHILE;
COMMIT;
CLOSE myCurs;
END
Примечание. В моем реальном сценарии:
- Я удаляю не все записи из таблицы, а только определенные по каким-то дополнительным критериям; а также
- Я планирую выполнять COMMIT каждые N# итераций цикла WHILE (скажем, 500 или 1000), а не весь беспорядок, как описано выше; а также
- Я планирую УДАЛИТЬ несколько таблиц, а не только эту;
Но опять же, чтобы упростить, я протестировал приведенный выше код, и я вижу, что DELETE, кажется, фиксируются 1 за 1. Я основываюсь на следующем тесте:
- Я предварительно загружаю таблицу (скажем, 50 тыс.) Записями;
- затем запустите хранимую процедуру очистки, которая занимает ~ 60 секунд;
- в это время с другого клиента sql я постоянно «ВЫБЕРИТЕ СЧЁТ (*) ИЗ таблицы A» и вижу постепенное уменьшение счёта.
Если бы все DELETE были зафиксированы одновременно, я бы ожидал, что количество записей (*) упадет только с 0 до 0 в конце ~ 60 секунд. Это то, что я вижу с сопоставимыми SP, написанными для Oracle или SQLServer.
Это DB2 v9.5 на Win2003.
Любые идеи, что мне не хватает?
DELETE
, но есть способы справиться с этим — например, вставка идентификаторов во временную таблицу или что-то подобное. 60 секунд всего за 50 000 записей — это довольно медленно — вы выполняете прямое чтение таблицы (или, возможно, индекса), поэтому большую часть времени занимает циклическая логика и последовательное удаление строк. - person Clockwork-Muse   schedule 10.02.2014