powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / В чем может быть причина замедления FORALL INSERT?
25 сообщений из 66, страница 2 из 3
В чем может быть причина замедления FORALL INSERT?
    #39837988
MinistrBob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
FogelMinistrBob....
Нужно перебросить таблицу размером 30Тб из одного ТП в другое, потому что уже максимум файлов в ТП - 1022
....

MinistrBob....
Но на самом деле когда система вводилась в эксплуатацию лет 7 назад, никто и не предполагал что таблицы будут разрастаться до таких размеров, и ведь ничего оттуда удалять нельзя - все нужное.
....

мало кто знает, что будет с ним через 7 лет, не говоря уже о самой идеальной системе, созданной здесь и сейчас.
Вам(Тебе) нужно не xyйнёй "экстренная тех.поддержка" заниматься, а рефакторить архитектуру, разбив эту неебическую таблицу на множества: партиции, но тут, боюсь, даже они уже не вытянут, а лучше разные таблицы по периодам (кстати до появления партиций вполне себе работающий и, кстати, до сих пор на некоторых системах древней разработки, метод).

Просто так менять что-то в промышленной системе? Заказчику было предложена новая версия ПО, но он не хочет и это его право. А без его решения и оплаты, зачем что-то менять, тем более там не только БД придется менять но еще и приклад. Это вопрос не технический, а организационный.
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39837996
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MinistrBob,

Если так хочется отдельное ТС для таблицы и она занимает б о льшую часть, перенеси из ТС другие объекты.
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39837997
MinistrBob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymousMinistrBobпропущено...

По поводу трассировки хорошая идея, только заказчик не даёт доступ к серверу непосредственно, у меня есть только машина с Toad и учёткой пользователя sysdba, а вот sys у меня нет.
Из Toad можно конечно запустить трассировку, но как потом получить файл, а самое главное его обработать, чего-то не хочеться в сыром трейсе копаться.
Этого более чем достаточно.

Код: plsql
1.
2.
3.
4.
select value from v$system_parameter where name like 'user_dump_dest';
create directory user_dump_dest as '<результат предыдущего запроса>';
select tracefile from v$process where addr in (select paddr from v$session where sid=<трассируемая сессия>);
select bfilename('user_dump_dest','<имя файла>') from dual;



Обработать - можно хоть штатным tkprof, хоть orasrp.

MinistrBobЗапрос гребет из опорной таблицы в которой просто список ID переносимых строк, чтобы понимать что уже перенесено.


После вставки порции 10000 этаже порция ID удаляется из этой таблицы, т.е. да она постоянно обновляется, насчёт интенсивно или нет - не знаю. А что тут можно сделать?
Напрасно.
Просто логируйте максимальный перенесенный вашей же процедурой ID в отдельную табличку и отбирайте по критерию неравенства.

MinistrBobВот текст типовой процедуры (одна из 10).

Избавьтесь от delete, он не нужен.

Отдельное спасибо за процедуру трассировки без доступа к серверу!

Toad позволяет получить ADDM - но там ничего критичного, самое большое ожидание сессии - direct path read. А что сделаешь с этим, я полагаю что ничего. В конечно итоге всё упирается в железо.

Смысл все канители с удалениями в том что там 10 таких процедур параллельно запускаються - это раз, а еще всё это частенько падает или останавливается - т.е. нужно много кратно перезапускать. Я раньше делал, без опорной таблицы, через minus выявлял что уже перенесено, но на огромных объемах этот minus работал часами и каждый перезапуск очень долго запускался.
С опорной таблицей всё гораздо быстрее.
А замеры времени каждого куска кода показали что медленнее всего именно insert, а delete на его фоне в разы быстрее.
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838002
MinistrBob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
feagorandrey_anonymous,

Я бы на месте автора сделал бы немного по другому.
Создал бы таблицу, содержащую инфу для параллельной обработки, в которой бы хранил диапазоны ID, которые необходимо перенести в рамках одной таски

....

как вариант почитайте еще про DBMS_PARALLEL_EXECUTE

В механизме есть такая таблица, посмотри курсор в процедуре выбирает один чанк

Код: plsql
1.
2.
3.
OPEN l_cursor FOR
      select d.* from ela_document d 
      where d.elado_document_id in (select id from ela_doc_chunks where chunk# = 10);



Таких чанков 10. Таблица создаётся так

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE TABLE ELA_DOC_CHUNKS
(
   ID       NUMBER,
   CHUNK#   NUMBER
)
TABLESPACE USERS
NOLOGGING;

INSERT INTO ELA_DOC_CHUNKS (ID, CHUNK#)
   SELECT ELADO_DOCUMENT_ID, ORA_HASH (ELADO_DOCUMENT_ID, 10) AS chunk#
     FROM ela_document;



А параллельность обеспечивается тем что 10 чанков запускаются через DBMS_SCHEDULER (вместо DBMS_PARALLEL_EXECUTE)
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838006
MinistrBob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
feagorПлюс нужно понимать, что параллельные insertы не всегда работают лучше одиночного, так как работа в таком режиме идёт в основном с дисками, а не с CPU(10046 level 8 покажет какие ожидания доминируют, как уже сказали выше)


Я провел эксперимент и в insert заменил хин append (который не работает = игнорируется из-за фразы values в insert) на append_values. Только пришлось запустить в один поток, потому что при такой вставке таблица эксклюзивно блокируется и если запустить несколько потоков параллельно, они тупо стоят и ждут.
И append_values работает гораздо быстрее, за счёт реальной direct вставки, но замеры временных показателей показали, что несмотря на то что каждый в отдельности процесс append выполняется медленнее append_values но за счёт того что их 10, они параллельно быстрее раза в два ушатают всю таблицу.

Так что отказался от идеи append_values и одного процесса.
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838010
MinistrBob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
кит северных морейMinistrBobСмысл в PL\SQL и разбиении на маленькие порции в задаче.
Нужно перебросить таблицу размером 30Тб из одного ТП в другое, потому что уже максимум файлов в ТП - 1022 и больше его расширять не получиться.
На оборудовании заказчика такая операция оценочно идет 20-30 дней.
Поэтому нужен процесс переноса, который можно перезапускать многократно.
Пробовали alter table ... move и dbms_redefinition - не подходит в данном случае. Если эти процессы падают, а они падают это время и не один раз, а еще иногда просят остановить всё потому что тормозит всё сильно. Поэтому нужен полностью управляемый код, который можно править как хочешь.
виртуально делите исходную таблицу на N сопоставимого размера кусков, через dbms_parallel_execute.create_chunks_by_rowid/create_chunks_by_number_col, либо DIY parallelism .

куски грузим последовательно, в один поток, но с enable_parallel_dml и выставленным DOP. примерно так:
Код: plsql
1.
2.
3.
4.
5.
6.
begin 
for c in (select start_rowid, end_rowid from DBA_PARALLEL_EXECUTE_CHUNKS ) loop
insert /*+append parallel(32) no_gather_optimizer_statistics*/ into target select * from source where rowid between c.start_rowid and c.end_rowid;
commit;
end loop;
end;


конкретные N и DOP подбирать по ситуации и тестировать. чем меньше N, тем меньше времени займет процесс от начала до конца, но тем выше будет цена падения процесса загрузки одного куска.

Вот это интересно, покурю :)
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838012
oragraf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MinistrBob,

Сделай вставку в 10 потоков с append_values в 10 таблиц, потом их склей в партиции целевой таблицы
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838013
MinistrBob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
watsonMinistrBobТаких процедур выполняется 10 шт, т.е. 10 потоков, и в каждом потоке еще и вставка идет порциями по 10000 строк.

Интересно, как у вас работает параллельная вставка из нескольких потоков в одну и ту же таблицу с хинтом APPEND?

Нормально работает. Из за фразы values в insert хинт append просто игнорируется и выполняются обычные (conventional) insert.
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838015
MinistrBob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-2-MinistrBob,

Если так хочется отдельное ТС для таблицы и она занимает б о льшую часть, перенеси из ТС другие объекты.

Уже сделано, но там других объектов было с гулькин нос, так что освободившееся место даст времени на перенос таблицы.
Кроме этого из самой таблицы удалили всё что только можно, но удалить там можно было тоже очень мало чего.
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838018
MinistrBob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
oragrafMinistrBob,

Сделай вставку в 10 потоков с append_values в 10 таблиц, потом их склей в партиции целевой таблицы

А чего можно отдельные таблицы склеивать в партиционированную таблицу? по какому тогда признаку они будут у меня партиционироваться, вставка ведь беспорядочно идет?
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838021
Фотография кит северных морей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MinistrBob-2-MinistrBob,

Если так хочется отдельное ТС для таблицы и она занимает б о льшую часть, перенеси из ТС другие объекты.

Уже сделано, но там других объектов было с гулькин нос, так что освободившееся место даст времени на перенос таблицы.
Кроме этого из самой таблицы удалили всё что только можно, но удалить там можно было тоже очень мало чего. само по себе удаление данных из таблицы, без дополнительных телодвижений, не освобождает место в ТП - только в самой таблице и только для conventional insert.

возможно вам имеет смысл секционировать таблицу, например по какой-то дате, и хранить каждую секцию в своем tablespace, пропорциональном размеру секции (например секция размером в месяц, ТП размером в год, в нем 12 секций).
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838022
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MinistrBobА чего можно отдельные таблицы склеивать в партиционированную таблицу?Можно обменивать таблицу и партицию.MinistrBob-2-Если так хочется отдельное ТС для таблицы и она занимает б о льшую часть, перенеси из ТС другие объекты.Уже сделано, но там других объектов было с гулькин нос, так что освободившееся место даст времени на перенос таблицы.
Кроме этого из самой таблицы удалили всё что только можно, но удалить там можно было тоже очень мало чего.Если TS и так не занят другими объектами, в чем тогда смысл переливания из пустого в порожнее.
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838034
feagor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MinistrBobВ механизме есть такая таблица, посмотри курсор в процедуре выбирает один чанк
Попробуйте понять разницу между "хранятся копии всех айдишников" и "хранятся диапазоны".
вы в рамках каждой таски сейчас делаете удаление такого же количества записей, какое и вставляете в новую таблицу. в то время, как от этого можно(нужно) отказаться+доп.расходы на коллекции, которые в общем то тоже не особо нужны
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838193
watson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MinistrBob
ElicНе гонять через PL/SQL.

Смысл в PL\SQL и разбиении на маленькие порции в задаче.
Нужно перебросить таблицу размером 30Тб из одного ТП в другое, потому что уже максимум файлов в ТП - 1022 и больше его расширять не получиться.
На оборудовании заказчика такая операция оценочно идет 20-30 дней.
Поэтому нужен процесс переноса, который можно перезапускать многократно.
Пробовали alter table ... move и dbms_redefinition - не подходит в данном случае. Если эти процессы падают, а они падают это время и не один раз, а еще иногда просят остановить всё потому что тормозит всё сильно. Поэтому нужен полностью управляемый код, который можно править как хочешь.



А как вариант, разбить табличку на бОльшее количество чанков. На столько, чтобы вставка одного чанка занимала "малое" время.
Тогда вместо FORALL
Код: plsql
1.
2.
insert into t1
select * from t2 where chunk_id = :1;



И оставить те же 10 параллельных потоков для обработки, условно, 1000 небольших чанков.
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838760
MinistrBob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
кит северных морейMinistrBobпропущено...


Уже сделано, но там других объектов было с гулькин нос, так что освободившееся место даст времени на перенос таблицы.
Кроме этого из самой таблицы удалили всё что только можно, но удалить там можно было тоже очень мало чего. само по себе удаление данных из таблицы, без дополнительных телодвижений, не освобождает место в ТП - только в самой таблице и только для conventional insert.

возможно вам имеет смысл секционировать таблицу, например по какой-то дате, и хранить каждую секцию в своем tablespace, пропорциональном размеру секции (например секция размером в месяц, ТП размером в год, в нем 12 секций).

Заказчик боится такие действия делать. Мотивируется это тем что работу приклада с партиционированными таблицами никто не тестировал, поэтому нефиг это делать.
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838767
MinistrBob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-2-MinistrBobА чего можно отдельные таблицы склеивать в партиционированную таблицу?Можно обменивать таблицу и партицию.MinistrBobпропущено...
Уже сделано, но там других объектов было с гулькин нос, так что освободившееся место даст времени на перенос таблицы.
Кроме этого из самой таблицы удалили всё что только можно, но удалить там можно было тоже очень мало чего.Если TS и так не занят другими объектами, в чем тогда смысл переливания из пустого в порожнее.

Потому что единственный сегмент в этом ТП, таблица которая сейчас переносится в другое ТП, разросся до размеров ТП. А увеличить ТП нельзя, т.к. достигнуто предельное количество файлов = 1022. Новое ТП создано с большим размером блока = 16Кб и поэтому таблица переезжает сюда чтобы иметь возможность расти дальше.
Про партиционирование написал выше - заказчик пока против партиционирования.
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838769
MinistrBob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
feagorMinistrBobВ механизме есть такая таблица, посмотри курсор в процедуре выбирает один чанк
Попробуйте понять разницу между "хранятся копии всех айдишников" и "хранятся диапазоны".
вы в рамках каждой таски сейчас делаете удаление такого же количества записей, какое и вставляете в новую таблицу. в то время, как от этого можно(нужно) отказаться+доп.расходы на коллекции, которые в общем то тоже не особо нужны

Спасибо, присмотрюсь повнимательнее, попробую понять разницу.
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838776
MinistrBob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
watson
А как вариант, разбить табличку на бОльшее количество чанков. На столько, чтобы вставка одного чанка занимала "малое" время.
Тогда вместо FORALL
Код: plsql
1.
2.
insert into t1
select * from t2 where chunk_id = :1;



И оставить те же 10 параллельных потоков для обработки, условно, 1000 небольших чанков.


Да как вариант. Это похоже на то что предлагает feagor . Можно будет попробовать.
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39838826
IMNO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
оффтопandrey_anonymous
Код: plsql
1.
2.
3.
4.
select value from v$system_parameter where name like 'user_dump_dest';
create directory user_dump_dest as '<результат предыдущего запроса>';
select tracefile from v$process where addr in (select paddr from v$session where sid=<трассируемая сессия>);
select bfilename('user_dump_dest','<имя файла>') from dual;




Почему ни одна редиска не скинула мне подобный кусок в моей теме ? Это что какое-то тайное знание?

Два чая джентльмену andrey_anonymous!
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39842488
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IMNOПочему ни одна редиска не скинула мне подобный кусок в моей теме ?
https://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1271615&msg=21546909
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39842636
feagor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous
Код: plsql
1.
select value from v$system_parameter where name like 'user_dump_dest';



Кстати не всегда указывает туда куда надо.
Пока самым надежным вариантом кажется такой
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
declare
  vpath varchar2(500);
  slash char(1);
  function is_windows_server return int is
  begin
    if instr(dbms_utility.port_string, 'WIN_') > 0 then
      return 1;
    else
      return 0;
    end if;
  end;
begin
  slash := case is_windows_server when 1 then '\' else '/' end;
  select substr(tracefile,1,instr(tracefile, slash, -1))
  into   vpath
  from   v$process
  where  rownum = 1;
  DBMS_OUTPUT.PUT_LINE(vpath);
end;
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39842643
feagor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
feagorКстати не всегда указывает туда куда надо.

Пример, когда из всех параметров правильно указывал только _diag_adr_trace_dest
12.2с
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39842699
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MinistrBobВ чем может быть причина замедления FORALL INSERT?

Несколько разных сессий выполняют вот такую процедуру вставки строк. Процедура приведена не полностью, но замеры времени выполнения участков кода, показывают что именно время выполнение этого кода возрастает.

Здесь выполняется INSERT через FORALL порциями по 10000 строк. Таблица, в которую выполняется вставка, совершенно пустая – вновь созданная, нет никаких триггеров, никаких индексов , но она LOGGING. Чем дальше, тем больше становиться время вставки порции строк. Т.е. скорость процесса всё время плавно уменьшается.

Хинт APPEND здесь не работает (это подтверждается планом в котором говориться что conventional insert (не direct)). Пробовал заменить на APPEND_VALUES – в этом случае сессии начинают блокировать друг друга, появляется ожидание «enq: TM – contention» и всё тормозит еще сильнее.

Ожидания этой сессии, отсортировано по TIME_WAITED, ничего криминального тут не вижу.
EVENT;TIME_WAITEDdirect path read;262343db file sequential read;9715read by other session;6161db file parallel read;736direct path read temp;426Disk file operations I/O;218direct path write temp;81direct path write;46latch: cache buffers chains;9library cache load lock;7log file switch (private strand flush incomplete);3cursor: pin S wait on X;2library cache: mutex X;1events in waitclass Other;1latch: shared pool;0latch: row cache objects;0enq: HW - contention;0buffer busy waits;0


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
BEGIN
   OPEN l_cursor FOR
      SELECT *
        FROM ela_document
       WHERE id BETWEEN X1 AND X2;

   LOOP
      BEGIN
         FETCH l_cursor BULK COLLECT INTO l_data LIMIT 10000;

         FORALL i IN 1 .. l_data.COUNT
            INSERT /*+ APPEND */
                  INTO  ela_document_copy
                 VALUES l_data (i);

         COMMIT;
      END;

      EXIT WHEN l_cursor%NOTFOUND;
   END LOOP;
END;
/



В чём может быть причина постепенного замедления процесса? И как это исправить?
если уж такой критический случай, я бы сделал объектный тип верхнего уровня с коллекцией, в которую бы фетчил курсор балками тыщ по двадцать-тридцать, и инсертел бы INSERT /*+APPEND PARALLEL*/ INTO ela_document_copy SELECT * FROM TABLE(:X), а коммит делал бы после примерно десяти таких инсертов. Предварительно конечно надо было бы делать ALTER SESSION ENABLE PARALLEL DML
(не прав?)
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39842792
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--,

Ты тоже не понимаешь, что значит "не гонять через PL/SQL"? А через объекты тем паче?
...
Рейтинг: 0 / 0
В чем может быть причина замедления FORALL INSERT?
    #39842943
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic,

хорошо, а каким способом фетчить курсор в коллекцию, а затем вставлять as select, не гоняя через PL/SQL?
...
Рейтинг: 0 / 0
25 сообщений из 66, страница 2 из 3
Форумы / Oracle [игнор отключен] [закрыт для гостей] / В чем может быть причина замедления FORALL INSERT?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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