Оптимальный запрос при использовании update в for select

MIRNIY
Дата: 27.11.2009 10:22:41
Имеется большая таблица, при выборке больших объемов данных (около 600 тыс.) и манипуляции с ними (время около 2 часов), запрос ломается на snapshot error. Решением стало: создание временной таблицы, и запись туда с одним параметром, тем самым мы после отработки селекта с главной таблицы, дальше работаем с временной. Главный селект отрабатывает около - 15-20 мин.

Но вот задача, в for in (select * from TEMP_TABLE) нужно использовать UPDATE для обновлении некоторых аттрибутов. Как можно оптимальней сделать данный запрос? Селект по каждой записи занимается более 10-50 сек.

Прошу помочь. По главной таблице выборке делается по индексу bitmap, во временной таблице также есть индексы.
Вячеслав Любомудров
Дата: 27.11.2009 10:30:09
Сделай сначала select for update по главной, а затем ее спокойно правь
И обойдешься без временной
Maxifly
Дата: 27.11.2009 14:18:08
Вячеслав Любомудров
Сделай сначала select for update по главной, а затем ее спокойно правь
И обойдешься без временной


Правильно я понял:
Вы предлагаете сначала сделать
select for update всех этих 600 тыс. записей из большой таблицы.
Потом править их в этой самой большой таблице в течении тех самых 2-х часов

и тогда не случится на snapshot to old?
andrey_anonymous
Дата: 27.11.2009 14:29:25
Maxifly
и тогда не случится на snapshot to old?

если commit-иться не будете в процессе и не будете злоупотреблять согласованием на начало операции - не случится.
Тут Ваши главные враги - конкурирующие dml-транзакции, которые замрут на два часа, и недостаточный объем undo :)
Maxifly
Дата: 27.11.2009 14:31:55
andrey_anonymous

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


Что есть согласование на начало операции?
andrey_anonymous
Дата: 27.11.2009 14:38:07
Maxifly
andrey_anonymous

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


Что есть согласование на начало операции?


declare 
cursor c is select * from big_table;
cursor cu is select * from big_table for update;
begin
  open c;
  for i in cu loop
    update big_table where current of...
  end loop;
  FETCH C INTO...
end;

Другой вариант злоупотреблений - установить в сессии режим изоляции serializable и делать по ходу пьессы отдельные запросы к big_table.
MIRNIY
Дата: 28.11.2009 00:00:32
тут еще вот какие ограничения есть:
- использование временной таблицы помогает дальше работать с данными (делать group by, находить суммы)
- я не являюсь администратором БД и нет таких прав, по крайней мере на остановку других процессов.
- данная большая таблица является общей и главной для всех сотрудников, все им пользуются, даже при запуске отчета.

извините, а что нам даст select for? блокирование других процессов обращающихся к данной таблице не лучший вариант. =)

есть еще какие нибудь варианты? может дело в использовании индексов?
кстати, операцию commit выполняю после цикла, вот так for r in select () loop .. end loop; commit.
Elic
Дата: 28.11.2009 00:14:57
MIRNIY
Имеется большая таблица, при выборке больших объемов данных (около 600 тыс.) и манипуляции с ними (время около 2 часов), запрос ломается на snapshot error.
По главной таблице выборке делается по индексу bitmap
Надо нанять того, кто понимает, чего не следует делать бездумно
MIRNIY
Дата: 28.11.2009 00:41:09
нанять не получится, моя обязанность сделать все качественно и быстро.
есть решения? неужели никто не сталкивался с таким...