Локальная временная таблица в Oracle 10 (для объема хранимой процедуры)

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

Есть ли способ создать временные таблицы таким образом, чтобы разные экземпляры таблиц создавались для каждого вызова хранимой процедуры, чтобы данные из нескольких вызовов хранимой процедуры не смешивались?


person Babar    schedule 28.07.2009    source источник


Ответы (4)


Вы говорите, что вы новичок в Oracle. Я предполагаю, что вы привыкли к SQL Server, где довольно часто используются временные таблицы. Oracle работает по-другому, поэтому он менее распространен, потому что он менее необходим.

Bear in mind that using a temporary table imposes the following overheads:

  1. read data to populate temporary table
  2. write temporary table data to file
  3. read data from temporary table as your process starts
Most of that activity is useless in terms of helping you get stuff done. A better idea is to see if you can do everything in a single action, preferably pure SQL.


Кстати, ваше упоминание о пуле соединений поднимает еще одну проблему. Процесс, обрабатывающий большие объемы данных, не является хорошим кандидатом для работы в режиме OLTP. Вам действительно следует подумать об инициировании фонового (то есть асинхронного) процесса, возможно, задания базы данных, для запуска вашей хранимой процедуры. Это особенно верно, если вы хотите запускать это задание на регулярной основе, потому что мы можем использовать DBMS_SCHEDULER для автоматизации управления такими вещами.

person APC    schedule 28.07.2009

ЕСЛИ вы используете временные таблицы уровня транзакций (а не сеанса), то это может уже делать то, что вы хотите... до тех пор, пока каждый вызов содержит только одну транзакцию? (вы не предоставляете достаточно подробностей, чтобы понять, так это или нет)

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

(Другим вариантом было бы создание временной таблицы с уникальным именем в каждом вызове с использованием EXECUTE IMMEDIATE. Хотя не уверен, насколько это будет эффективно.)

person cagcowboy    schedule 28.07.2009
comment
+1: вам не нужно заново создавать временные таблицы для каждого сеанса. Создайте временную таблицу ОДИН РАЗ, и каждый сеанс будет видеть только свои данные. - person Vincent Malgrat; 28.07.2009

В Oracle практически никогда не требуется создавать объекты во время выполнения.

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

Тем не менее, я довольно успешно использовал глобальные временные таблицы в прошлом в приложениях, которым нужно было поддерживать отдельное «пространство» в таблице для нескольких контекстов в одном сеансе; это делается путем добавления дополнительного столбца идентификатора (например, «CALL_ID»), для которого изначально установлено значение 1, и последующие вызовы процедуры будут увеличивать этот идентификатор. Идентификатор обязательно будет запомнен с использованием глобальной переменной где-нибудь, например. глобальная переменная пакета, объявленная в теле пакета. НАПРИМЕР.:

PACKAGE BODY gtt_ex IS
   last_call_id integer;
   PROCEDURE myproc IS
      l_call_id integer;
   BEGIN
      last_call_id := NVL(last_call_id, 0) + 1;
      l_call_id      := last_call_id;
      INSERT INTO my_gtt VALUES (l_call_id, ...);
      ...
      SELECT ... FROM my_gtt WHERE call_id = l_call_id;
   END;
END;

Вы обнаружите, что GTT работают очень хорошо даже при высокой степени параллелизма, определенно лучше, чем при использовании обычных таблиц. Лучшей практикой является разработка приложения таким образом, чтобы ему никогда не приходилось удалять строки из временной таблицы, поскольку GTT автоматически очищается после завершения сеанса.

person Jeffrey Kemp    schedule 28.07.2009

Недавно я использовал глобальную временную таблицу, и она вела себя очень нежелательно.

Я использовал временную таблицу для форматирования некоторых сложных данных в вызове процедуры, и после того, как данные отформатированы, передал данные на передний конец (Asp.Net). При первом вызове процедуры я использовал для получения правильных данных, а любой последующий вызов использовал для получения данных из последнего вызова процедуры в дополнение к текущему вызову.

Я исследовал сеть и обнаружил возможность удалять строки при фиксации. Я думал, что это решит проблему .. угадайте, что? когда я использовал опцию удаления строк фиксации, я всегда получал 0 строк из базы данных. поэтому мне пришлось вернуться к исходному подходу сохранения строк при фиксации, который сохраняет строки даже после фиксации транзакции. Этот параметр очищает строки из временной таблицы только после завершения сеанса. затем я узнал об этом сообщении и узнал о столбце для отслеживания call_id сеанса.

Я реализовал это решение, и все же это не решает проблему. затем я написал следующий оператор в своей процедуре, прежде чем начать какую-либо обработку.

Удалить из Temp_table

Вышеупомянутый statemnet сделал свое дело. мой внешний интерфейс использовал пул соединений, и после каждого вызова процедуры он совершал транзакцию, но по-прежнему сохранял соединение в пуле соединений, а последующий запрос использовал одно и то же соединение, и, следовательно, сеанс базы данных не прерывался после каждого вызова. Удаление строк из temp таблица перед тем, как начать какую-либо обработку, заставила ее работать....

Это сводило меня с ума, пока я не нашел это решение....

person Amit    schedule 04.12.2009