Мне кажется, я вижу, что ты пытаешься сделать.Я хочу высказать несколько замечаний относительно различий между приведенным ниже кодом и вашим.
- Ваш
forall
цикл не будет использовать индекс.Это легко обойти, используя rowid
для обновления вашей таблицы. - Подтверждая после каждого
forall
, вы уменьшаете количество необходимых отмен;но затруднить откат, если что-то пойдет не так.Хотя логически ваш запрос может быть легко перезапущен посередине и без ущерба для вашей цели. rowids
малы, собирайте не менее 25 тыс. Одновременно;если не 100k. - Вы не можете индексировать ноль в Oracle.На стеке есть много вопросов об этом, вам нужно больше информации.Функциональный индекс на что-то вроде
nvl(date_origin,'x')
в качестве свободного примера увеличит скорость, с которой вы выбираете данные.Это также означает, что вам никогда не придется использовать саму таблицу.Вы выбираете только из индекса. - Ваш тип данных даты выглядит как строка.Я сохранил это, но это не разумно.
- Если вы можете заставить кого-то увеличить размер отменяемого табличного пространства, тогда обновление будет быстрее.
Предполагается, что согласно вашим комментариямdate_origin
- это дата, тогда индекс должен быть примерно таким:
nvl(date_origin,to_date('absolute_minimum_date_in_Oracle_as_a_string','yyyymmdd'))
У меня нет доступа к БД в данный момент, но чтобы узнать amdiOaas
, запустите следующий запрос:
select to_date('0001','yyyy') from dual;
Это должно вызвать полезную ошибку для вас.
Рабочий пример в PL / SQL Developer.
create table main_tbl as
select cast( null as date ) as date_origin
from all_objects
;
create index i_main_tbl
on main_tbl ( nvl( to_date(date_origin,'yyyy-mm-dd')
, to_date('0001-01-01' ,'yyyy-mm-dd') )
)
;
declare
cursor c_rec is
select rowid
from main_tbl
where nvl(date_origin,to_date('0001-01-01','yyyy-mm-dd'))
= to_date('0001-01-01','yyyy-mm-dd')
;
type t__rec is table of rowid index by binary_integer;
t_rec t__rec;
begin
open c_rec;
loop
fetch c_rec bulk collect into t_rec limit 50000;
exit when t_rec.count = 0;
forall i in t_rec.first .. t_rec.last
update main_tbl
set date_origin = to_date('23-JAN-2012','DD-MON-YYYY')
where rowid = t_rec(i)
;
commit ;
end loop;
close c_rec;
end;
/