Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Clob to blob / 6 сообщений из 6, страница 1 из 1
06.09.2017, 11:53
    #39516315
Pir
Pir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Clob to blob
Всем привет!
Подскажите как лучше конвертировать столбец из clob в blob
Таблица партицированная, 140 млн записей, около 2 тб

Я создал blob столбец и стал конвертировать пачками по 10000

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
DECLARE
  JOB_PREFIX      VARCHAR2(50):='CLOB_TO_BLOB_';
  v_rows_count    int;
  v_part_count    int;
  v_commit_count  int         := 10000;
BEGIN
  select count(*) into v_rows_count from big_table;
  v_part_count := greatest(round(v_rows_count/v_commit_count),1);
  for i in 0..v_part_count loop
       DBMS_SCHEDULER.CREATE_JOB(JOB_NAME    => JOB_PREFIX || i, 
                                 JOB_TYPE    => 'PLSQL_BLOCK', 
                                 JOB_ACTION  =>
                                 'update big_table t set 
                                   t.col_blob = clob_to_blob(t.col_clob)
                                  where MOD(ORA_HASH(t.rowid), ' || v_part_count || ') = ' || i || ';
                                 
                                 commit;',
                                 START_DATE  => SYSDATE,
                                 ENABLED=> TRUE);
  end loop;
END;
/



Но джобы падают с snapshot too old: rollback segment number 37 with name "_SYSSMU37_1974413906$" too small

Есть ли способ проще?
...
Рейтинг: 0 / 0
06.09.2017, 12:01
    #39516328
Бродячий Айтист
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Clob to blob
Pir,

это..
я бы предложил создать еще табличку big_table_2 без индексов

на big_table дропаешь индексы и инсертишь в big_table_2 bulk insert select чтоб не генерился откат

потом транкейтишь big_table и вставляешь обратно уже сконверченное из big_table_2 bulk insert select
...
Рейтинг: 0 / 0
06.09.2017, 12:18
    #39516351
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Clob to blob
Pir,

У тебя таблица партиционирована, а ты ее фуллсканами да еще и с динамическим SQL лопатишь.

1) Самый простой вариант - бей транзакции по партициям. В апдейте явно указывай имя партиции - список их ты получишь из словаря.
2) Если размер партиций слишком велик - то заморачивайся и бей транзакции по группам экстентов. Dba_extents + dbms_rowid тебе в помощь.
...
Рейтинг: 0 / 0
06.09.2017, 12:20
    #39516353
Pir
Pir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Clob to blob
Бродячий Айтист,

Там есть нюансы.. На таблице foreign key, который не снять. Т.к. она связана с родительской таблицей через ссылочное партиционирование.
И вообще это промышленная таблица с архивом документов за 5 лет. Я не готов ее потерять)
...
Рейтинг: 0 / 0
06.09.2017, 12:39
    #39516375
Fogel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Clob to blob
Pir
Код: plsql
1.
where MOD(ORA_HASH(t.rowid), ' || v_part_count || ') = ' || i || ';



Вот это условие согласно заявленной логике и наполнению переменных неправильно: могут возникать коллизии, когда на 1 поле попадает 2 джоба ( см. здесь ) - поэтому и падает со snapshot too old.
Джобы лучше создавать в рамках 1 партиции (доп условие) и если берёшь счётчик по кол-ву строк, то хэш здесь ни к чему, используй rownum
Для ускорения используй forall update
Пример:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
declare
  type t_cu_rou is table of rowid index by pls_integer;
  col_cu_rou t_cu_rou;
  rowallc    pls_integer;
begin
  select count(*)
    into rowallc
    from big_table c
   where условие партиции;
  for j in 1 .. (rowallc / 100000 + 1) loop
    select rowid bulk collect
      into col_cu_rou
      from big_table c
     where условие партиции
       and rownum < 100000;
    forall k_idx in col_cu_rou.first .. col_cu_rou.last
      update big_table t set 
        t.col_blob = clob_to_blob(t.col_clob)
        where rowid = col_cu_rou(k_idx);
  end loop;
end;
...
Рейтинг: 0 / 0
06.09.2017, 12:50
    #39516390
AmKad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Clob to blob
Fogel,

Что такое "условие партиции" и как сделать так, чтобы код не обновлял в цикле одни и те же (100000 - 1) записей?
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Clob to blob / 6 сообщений из 6, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]