Временные таблицы Oracle 10g

Я пытаюсь преобразовать постоянные таблицы, используемые в хранимой процедуре, в глобальные временные таблицы. Я просмотрел статистику по этим постоянным таблицам, и некоторые из них содержат десятки миллионов строк данных и имеют размер в гигабайтах (до 10 ГБ).

So,

CREATE TABLE my_table (  
  column1 NUMBER,  
  column2 NUMBER,  
  etc...  
)  
TABLESPACE BIGTABLESPACE  
NOLOGGING  
NOCOMPRESS  
NOCACHE  
NOPARALLEL  
MONITORING;  

должен стать

CREATE GLOBAL TEMPORARY TABLE my_table (  
  column1 NUMBER,  
  column2 NUMBER,  
  etc..  
)  
ON COMMIT PRESERVE ROWS;  

Я создаю эквивалентную глобальную временную таблицу со строками, которые должны сохраняться до конца сеанса для каждой существующей постоянной таблицы. Эта глобальная временная таблица будет использоваться в процедуре вместо постоянной таблицы.
(EXECUTE IMMEDIATE 'TRUNCATE ...' в начале и INSERT /*+ APPEND */ INTO позже)

Все постоянные таблицы были созданы в большом табличном пространстве BIGTABLESPACE

В документации Oracle указано, что глобальная временная таблица будет создана во временном табличном пространстве пользователя (я предполагаю, что это TEMP). Проблема заключается в том, что табличное пространство TEMP невелико, и экстенты не настроены на рост до размера, который мне нужен, чтобы они увеличивались во время процедуры.

Табличное пространство TEMP было создано при создании базы данных

create database "$oracle\_sid"  
   user sys identified by "$sys\_password"  
   user system identified by "$system\_password"  
   set default bigfile tablespace  
   controlfile   reuse  
   maxdatafiles  256  
   maxinstances  $maxinstances  
   maxlogfiles   16  
   maxlogmembers 3  
   maxloghistory 1600  
   noarchivelog  
   character set WE8MSWIN1252  
   national character set AL16UTF16  
   datafile  
      '$oracle\_home/oradata/$oracle\_sid/system01.dbf' size 512M  
   logfile  
      '$oracle\_home/oradata/$oracle\_sid/redo01.log' size 1G,  
      '$oracle\_home/oradata/$oracle\_sid/redo02.log' size 1G,  
      '$oracle\_home/oradata/$oracle\_sid/redo03.log' size 1G  
   sysaux datafile  
      '$oracle\_home/oradata/$oracle\_sid/sysaux01.dbf' size 256M  
   default temporary tablespace temp tempfile  
      '$oracle\_home/oradata/$oracle\_sid/temp01.dbf' size 5G  
   undo tablespace "UNDOTBS1" datafile  
      '$oracle\_home/oradata/$oracle\_sid/undotbs01.dbf' size 5G;  

Постоянные таблицы (которые я планирую заменить) изначально были созданы в табличном пространстве BIGTABLESPACE

-- 50G bigfile datafile size  
create bigfile tablespace "BIGTABLESPACE"  
datafile '$oracle\_home/oradata/$oracle\_sid/bts01.dbf' size 50G  
extent management local  
segment space management auto;  

Индексы постоянных таблиц были изначально созданы в табличном пространстве BIGTABLESPACE.

-- 20G bigfile datafile size  
create bigfile tablespace "BIGINDXSPACE"  
datafile '$oracle\_home/oradata/$oracle\_sid/btsindx01.dbf' size 20G  
extent management local  
segment space management auto;  
  • Возможна ли замена этих постоянных таблиц глобальными временными таблицами?
  • Табличное пространство TEMP столкнется с проблемой расширения табличного пространства TEMP. Есть ли способ создать глобальные временные таблицы и их индексы в табличных пространствах BIGTABLESPACE и BIGINDXSPACE?
  • Если нет, как я могу заставить табличное пространство TEMP вести себя как табличное пространство большого файла и добиться разделения индексов и таблиц?
  • Могу ли я создать два TEMP табличных пространства больших файлов и создать индексы в одном, а таблицы в другом?

Я хочу использовать глобальные временные таблицы, но объем данных, которые я обрабатываю в этой процедуре, кажется, выходит за рамки дизайна глобальных временных таблиц с отступами. Какие-либо предложения?


person Community    schedule 09.12.2009    source источник


Ответы (3)


Нет никакой пользы от разделения данных и индексов на отдельные табличные пространства, кроме как потенциально сделать администраторами баз данных более удобными группировку похожих объектов. Существует давний миф о том, что разделение индексов и данных было выгодно по соображениям производительности - это неверно.

Временные объекты должны (и должны) храниться во временном табличном пространстве. Вы можете увеличить размер своего табличного пространства TEMP или создать отдельное временное табличное пространство только для пользователей, которые будут владеть этими объектами, если вы хотите выделить эти большие временные таблицы в отдельное табличное пространство. Вы не можете (и не хотели бы) хранить их в своих постоянных табличных пространствах.

Однако с точки зрения архитектуры мне было бы очень любопытно, зачем нужны временные таблицы в вашей системе. Если у вас есть сеансы, которые записывают 10 ГБ во временные таблицы, а затем, предположительно, снова читают эти 10 ГБ, чтобы записать данные в другое место, я бы склонен подозревать, что есть более эффективные решения. В Oracle очень редко даже требуются временные таблицы - это гораздо чаще встречается в других базах данных, где читатели могут блокировать писателей, чтобы им нужно было копировать данные из таблиц, прежде чем работать с ними. Oracle не имеет таких ограничений.

person Justin Cave    schedule 09.12.2009
comment
Вот почему необходимы временные таблицы: база данных Oracle, над которой я работаю, имеет одного назначенного пользователя со всеми привилегиями и всеми грантами. Клиентское приложение на основе стандартного SQL используется для входа в систему от имени этого пользователя и запуска сеанса, во время которого может быть вызвана любая хранимая процедура. Эти хранимые процедуры используют постоянные таблицы. Я не хочу, чтобы выполняемая процедура одного сеанса перекрывалась с данными другого и перекрывала-дважды вставляла данные в постоянные таблицы, используемые в хранимой процедуре. - person ; 09.12.2009
comment
Но почему хранимые процедуры вообще записывают какие-либо временные данные в таблицы? В частности, 10 ГБ переходных данных. Это самый запутанный компонент дизайна. Если данные не записываются постоянно, то, вероятно, вы могли бы просто написать запрос к базовым таблицам, чтобы получить любые данные, которые нужны вашим процедурам. - person Justin Cave; 09.12.2009
comment
Временные данные записываются в таблицы из-за сложности. Данные собираются из нескольких постоянных исходных таблиц, затем обрабатываются (объединяются, фильтруются, вычисляются) и в конечном итоге добавляются к нескольким таблицам результатов (которые являются постоянными). Под соединением я подразумеваю внешнее, внутреннее или декартово, если необходимо. Под отфильтрованными я подразумеваю критерии предложения WHERE. Под расчетным я подразумеваю ВЫБОР вычислений / вызовов функций. Это сложный многоэтапный процесс, который лучше всего подходит для декларативного SQL. SQL отличается простотой. Кроме того, остались данные для отладки. - person ; 09.12.2009

Не думаю, что в вашем описании есть что-то, что делает GTT непривлекательным. Очевидно, что вам нужны очень большие временные табличные пространства, но вы не потребляете больше места в целом, если только вы не сильно использовали сжатие таблиц (недоступно в GTT по крайней мере до 10gR2). Изучите использование групп табличных пространств: http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/tspaces.htm#ADMIN01103

Использование группы табличных пространств, а не одного временного табличного пространства, может облегчить проблемы, вызванные тем, что одно табличное пространство не подходит для хранения результатов сортировки, особенно в таблице с множеством разделов. Группа табличных пространств позволяет серверам параллельного выполнения в одной параллельной операции использовать несколько временных табличных пространств.

Также не пренебрегайте использованием предложений факторизации подзапросов. Они часто могут заменить использование временных таблиц. Однако им может потребоваться столько же временного пространства для хранения, потому что большой набор результатов из SQFC может быть перенесен на диск, чтобы избежать потребления слишком большого объема памяти, поэтому вам все равно придется продолжить увеличение пространства TEMP. Они очень удобны, поскольку вам не нужно развертывать новый объект базы данных каждый раз, когда вам нужна новая временная таблица.

person David Aldridge    schedule 10.12.2009

Я посмотрел на глобальные временные таблицы большого размера для упражнения по миграции. Это сработало, но для отладки и отказа я в конце концов выбрал простые таблицы.

Если GTT не работают, подумайте либо о безопасности на уровне строк / VPD (или даже о представлениях). У вас может быть столбец, производный от sys_context ('USERENV', 'SESSIONID'), и использовать его, чтобы пользователь мог видеть только свои собственные данные.

Тем не менее, мысль о нескольких сеансах, одновременно работающих с многогигабайтными наборами данных, немного пугает.

PS. Я считаю, что для GTT, используемых через процедуру, используйте временное табличное пространство пользователя сеанса, а не временное табличное пространство владельца процедуры. Если вы можете получить сеансы как отдельные пользователи Oracle, у вас есть шанс распределить ввод-вывод файла по разным табличным пространствам.

person Gary Myers    schedule 09.12.2009