Я думаю, вы неправильно поняли - если вы откатитесь к точке сохранения, то Oracle должен отменить всю работу, выполненную после точки сохранения (при сохранении любой незафиксированной работы, которая была выполнена до точки сохранения).
Для временной таблицы Oracle лениво выделяет хранилище (временный сегмент для вашего сеанса), когда вы вставляете данные, и что когда данные выполняются (либо в конце сеанса, либо в конце транзакция, в зависимости от типа), она может просто освободить хранилище, а не отдельно удалять строки, а также то, что происходит, когда вы TRUNCATE для нормальной таблицы.
мне было интересно узнать, что случилось, если у вас есть точка сохранения до того любые данные вставленных и откат к этой точке сохранения - бы Oracle освободить хранилище, или будет держать хранения и удалить строки из внутри Это?
Получается прежний - он ведет себя как усеченный.
SAVEPOINT f0;
SELECT * FROM v$tempseg_usage; -- Should show nothing for your session
insert into table_1 values('one');
insert into table_1 values('two');
SELECT * FROM v$tempseg_usage; -- Should show a DATA row for your session
savepoint f1;
insert into table_1 values('three');
insert into table_1 values('four');
rollback to f1; -- Undo three and four but preserve one and two
SELECT * FROM v$tempseg_usage; -- Still shows a DATA row for your session
rollback to f0; -- Undo all the inserts
SELECT * FROM v$tempseg_usage; -- row for your session has gone
Причина этого важно то, что, когда вы делаете нормальное удаление - а не срезанной - то любое полное сканированию таблицы все равно придется просеять через все блоки данных, чтобы увидеть, если у них есть какие-либо данные в DML против пустой таблицы может потенциально повлечь за собой много ввода-вывода , если в таблице было много данных в это время раньше!
Я пытаюсь ускорить выполнение какого-то кода, который делает именно это: он перемещает некоторые вещи во временную таблицу в виде блокнота, отчасти поэтому он может присоединяться к постоянной таблице и возвращать результат вызывающему. Временная таблица предназначена только для этой процедуры, поэтому ее можно очистить в конце процедуры, но она может быть вызвана много раз в родительской транзакции, поэтому я не могу обрезать (TRUNCATE
- это DDL, и поэтому совершает транзакцию), но я не могу ее не очистить, или вызовы в рамках одной транзакции будут забирать строки друг друга. Устранение с помощью DELETE вызывает довольно много накладных расходов, тем более, что в таблице нет индекса, и поэтому выбор против него всегда будет полным сканированием.
Параметр, который я изучаю, должен иметь SAVEPOINT
в начале процедуры, выполнять мою временную работу, а затем откатываться обратно в точку сохранения непосредственно перед тем, как он вернет результат. Другой вариант может заключаться в том, чтобы поместить подпрограмму в автономную транзакцию, но это означало бы перенос кода C в хранимую процедуру PL/SQL и не будет работать в любом случае, если временную таблицу необходимо объединить с незафиксированными данными, вставленными вызывающим.
Обратите внимание, что я провел исследование в 12c - в этой версии были внесены некоторые улучшения во временные таблицы (см. https://oracle-base.com/articles/misc/temporary-tables), но я не думаю, что это влияет на поведение при сохранении точек.