Оптимальный запрос при использовании 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
нанять не получится, моя обязанность сделать все качественно и быстро.
есть решения? неужели никто не сталкивался с таким...