2015-05-12 4 views
0

Я прочитал, что точки сохранения в глобальных временных таблицах Oracle удаляют все данные, но когда я тестировал Oracle 11g, они работали как таблицы кучи. Может кто-нибудь объяснить?Сохранение точек в глобальных временных таблицах Oracle

insert into table_1 values('one'); 
insert into table_1 values('two'); 
savepoint f1; 
insert into table_1 values('three'); 
insert into table_1 values('four'); 

rollback to f1; 

-- the records in table are 2 records just like heap tables, but I read that 
-- savepoints in GTT truncates all the data 

ответ

0

Где вы это читали? Я подозреваю, что нет в Oracle SQL Reference. Поэтому объяснение простое: автор этого утверждения не проверял поведение глобальных временных таблиц. Либо это, либо вы читали описание какой-либо другой реализации SQL, например DerbyDB.

Для полноты давайте исключаем роль транзакции или области сеанса. Вот две глобальные временные таблицы:

create global temporary table gtt1 
    (col1 varchar2(30)) 
    ON COMMIT PRESERVE ROWS 
/

create global temporary table gtt2 
    (col1 varchar2(30)) 
    ON COMMIT DELETE ROWS 
/

Давайте запустим эксперимент по одной с объемом сессии:

SQL> insert into gtt1 values('one'); 

1 row created. 

SQL> insert into gtt1 values('two'); 

1 row created. 

SQL> savepoint f1; 

Savepoint created. 

SQL> insert into gtt1 values('three'); 

1 row created. 

SQL> insert into gtt1 values('four'); 

1 row created. 

SQL> rollback to f1; 

Rollback complete. 

SQL> select * from gtt1; 

COL1 
------------------------------ 
one 
two 

SQL> 

Тот же результат для таблицы с объемом сделки:

SQL> insert into gtt2 values('five'); 

1 row created. 

SQL> insert into gtt2 values('six'); 

1 row created. 

SQL> savepoint f2; 

Savepoint created. 

SQL> insert into gtt2 values('seven'); 

1 row created. 

SQL> insert into gtt2 values('eight'); 

1 row created. 

SQL> rollback to f2; 

Rollback complete. 

SQL> select * from gtt2; 

COL1 
------------------------------ 
five 
six 

SQL> 

На самом деле это не удивительно. В official Oracle documentation состояния:

«Определение временной таблицы сохраняется таким же образом, как определения обычных таблиц»

В основном они являются таблицы кучи. Различия:

  • области (видимость) данные
  • табличный используется для сохранения данных (глобальные временные таблицы записи на временный табличный).
0

Я думаю, вы неправильно поняли - если вы откатитесь к точке сохранения, то 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), но я не думаю, что это влияет на поведение при сохранении точек.

 Смежные вопросы

  • Нет связанных вопросов^_^