Пиша 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. Базирам това на следния тест:
- Предварително зареждам таблицата с (да речем 50k) записи;
- след това изпълнете purge storedProc, което отнема ~60 секунди за изпълнение;
- през това време от друг sql клиент непрекъснато „ИЗБЕРЕТЕ БРОЙ(*) ОТ таблицаA“ и виждам, че броят намалява постепенно.
Ако всички DELETE бяха извършени наведнъж, бих очаквал да видя броя на записите (*) да спадне от 0 само в края на ~60 секунди. Това е, което виждам при сравними SP, написани за Oracle или SQLServer.
Това е DB2 v9.5 на Win2003.
Някакви идеи какво пропускам?
DELETE
s, но има начини да се справите с това - като вмъкване на идентификатори във временна таблица или подобни. 60s само за 50k записа е доста бавен - вие правите директно четене през таблица (или евентуално индекс), така че по-голямата част от времето ви се отнема от логиката на цикъла и изтриването ред по агонизиращ ред. - person Clockwork-Muse   schedule 10.02.2014