Операция удаления периодически замедляется oracle 11g - PullRequest
0 голосов
/ 29 мая 2020

У нас есть таблица аудита в производственной среде, из которой мы ежедневно удаляем почти 15 миллионов данных (данные старше нескольких дней) в пакете PL / SQL. В хороший день этот запрос удаляет те же данные за 1,5 часа. Но периодически в некоторые дни это не удаляет тот же объем данных даже за 4 часа. В этой таблице нет триггера, и столбец Created проиндексирован.

DELETE FROM SIEBEL.CX_AUDIT_SEARCH
WHERE CREATED < '20-MAy-2020' AND rownum <= 10000;

Explain pla:

DELETE STATEMENT    ALL_ROWS    6   10000   180000                  
DELETE SIEBEL.CX_AUDIT_SEARCH                                   
COUNT(STOPKEY)                                  ROWNUM<=10000
INDEX(RANGE SCAN) SIEBEL.CX_AUDIT_SEARCH_U1 ANALYZED    6   170692  3072456             "CREATED"<'20-MAy-2020' 

Не могли бы вы предложить любую возможную причину.

Ответы [ 2 ]

1 голос
/ 29 мая 2020

Это немного длинновато для комментария.

Для этого процесса вы хотите разбить таблицу. Это сохраняет таблицу в отдельных «файлах» для каждого раздела. И разделы могут быть удалены - этот процесс намного быстрее, чем удаление строк.

Вы описали строки, которые нужно удалить, как строки старше определенной даты. Это идеальное место для решения по разделению.

Вы можете узнать больше об этом в документации . Я удивлен, что у вас может быть такая большая база данных и вы не знаете об этой функции.

0 голосов
/ 29 мая 2020

Очевидно, что это очень загруженный стол. 15 миллионов строк в день означает около 10416 строк в минуту, что означает, что в то время, когда вы удаляете эти строки, вставляются тысячи записей. Пока Oracle пытается удалить старые строки и обновить индекс CREATED, добавляются и фиксируются другие строки.

Я вижу, вы пытаетесь УДАЛИТЬ 10000 строк за раз. Я предполагаю, что вы совершаете фиксацию после этих 10000 строк, поэтому следующий подход может быть немного быстрее, потому что SELECT выполняется только один раз, и вы не повторно просматриваете 1500 раз занятую таблицу ...

declare 
cursor c_rowids is
  SELECT T.ROWID
      FROM SIEBEL.CX_AUDIT_SEARCH T
     WHERE CREATED < '20-MAy-2020';
type t_tbl_rowids is table of rowid;
tbl_rowids t_tbl_rowids;
begin
  open c_rowids;
  Loop
    fetch c_rowids bulk collect into tbl_rowids limit 10000;
    exit when tbl_rowids.count = 0;
    forall i in 1..tbl_rowids.count
      DELETE FROM SIEBEL.CX_AUDIT_SEARCH
        WHERE ROWID = tbl_rowids(i);

    COMMIT;
  End loop;
  close c_rowids;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...