Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Оптимальный способ очистки таблицы по критерию / 21 сообщений из 21, страница 1 из 1
12.08.2016, 19:03:32
    #39291298
--Eugene--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
Есть не секционированная таблица в несколько десятков GB.
Ежесуточно пополняется на несколько десятков млн. строк.
Ежесуточно нужно удалять несколько десятков млн. строк (не обязательно тех, что были добавлены за эти сутки).
Удаление происходит ночью в рамках одной транзакции по условию WHERE NUMBER_COLUMN = :A AND DATE_COLUMN < :B (индексы есть, если что).
При этом происходит переполнение UNDO (очевидно, параллельно происходит более другая работа).
Решено разбить одну транзакцию удаления на несколько. (секционирование пока не рассматривается в качестве решения)

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

Возможно, есть более лучший способ?

Подскажите, пожалуйста.
Спасибо.
...
Рейтинг: 0 / 0
12.08.2016, 19:39:28
    #39291308
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
--Eugene--оптимальное количество записей10000
...
Рейтинг: 0 / 0
12.08.2016, 19:45:44
    #39291311
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
--Eugene--,

Оптимальное 12345. Я даже скрипт тебе подарю.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
declare
   limit int := 12345;
begin

   loop
      delete from <your_table> where <your condition> and rownum <= limit;
      exit when sql%rowcount < limit;
      commit;      
   end loop;
   commit;

end;
/
...
Рейтинг: 0 / 0
12.08.2016, 22:59:21
    #39291355
--Eugene--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
-2-,

Почему именно 10000?
...
Рейтинг: 0 / 0
12.08.2016, 23:06:07
    #39291361
Fogel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
--Eugene--,

попробуй ещё так и сравни быстродействие c другими способами
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
declare
  row4del single_integer;
begin
  select count(1)
    into row4del
    from table
   WHERE NUMBER_COLUMN = :A AND DATE_COLUMN < :B;
  forall j in 1 .. (row4del / 100000 + 1)
    delete table
     where rowid in
           (select rowid
              from table
             WHERE NUMBER_COLUMN = :A AND DATE_COLUMN < :B
       and rownum < 100000);
    commit;
end;
...
Рейтинг: 0 / 0
12.08.2016, 23:30:49
    #39291365
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
--Eugene--,

Тебе пытались намекнуть про бредовость постановки.
Одно дело если б ты хоть мерил в блоках, поскольку 10000 строк это может быть 10000 блоков а может 50.
И то безотносительно нагрузки и размера анду это сферическая оптимизация в вакууме.

А так ты получишь разве что идиотские решения в духе "попробуй ещё так".
...
Рейтинг: 0 / 0
12.08.2016, 23:47:21
    #39291367
Fogel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
--Eugene--,
в любом случае вместо loop для своих циклов delete используй forall
только логику выборки под этот перечень продумай
примеры можно найти здесь .
...
Рейтинг: 0 / 0
13.08.2016, 00:21:47
    #39291369
Оптимальный способ очистки таблицы по критерию
Fogel--Eugene--,
в любом случае вместо loop для своих циклов delete используй forallты если сам не в состоянии прочиьать приводимые ссылки, то хотя бы обрати внимание с какой проблемой автор завел тему.
...
Рейтинг: 0 / 0
13.08.2016, 03:16:27
    #39291374
--Eugene--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
dbms_photoshopОдно дело если б ты хоть мерил в блоках, поскольку 10000 строк это может быть 10000 блоков а может 50.
И то безотносительно нагрузки и размера анду это сферическая оптимизация в вакууме.Разве не понятно что размер UNDO известен, как и размер блока.
Допустим, все строки таблицы примерно одной длины (в байтах). Таким образом, можно получить среднее отношение (кол-во строк / кол-во блоков).
Прочая нагрузка на базу во время удаления неизвестна, это верно. Но возможно получить размер используемого/свободного пространства UNDO через системные вьюхи.
...
Рейтинг: 0 / 0
13.08.2016, 03:27:50
    #39291375
Rinka777
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
объем транзакции удаления определяется опытным путем. делаем цикл на 1000 записей, смотрим на реакцию. делаем цикл на 10 000 записей - сморим на реакцию. на 5000. сравниваем. думаем.
имхо. такое удаление ведет к разреживанию индексов и замедлению поиска по таблице. и место на диске ест. настоятельно рекомендую подумать в сторону партиционирования.
...
Рейтинг: 0 / 0
13.08.2016, 06:21:11
    #39291379
Вячеслав Любомудров
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
Fogel--Eugene--,

попробуй ещё так и сравни быстродействие c другими способами
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
declare
  row4del single_integer;
begin
  select count(1)
    into row4del
    from table
   WHERE NUMBER_COLUMN = :A AND DATE_COLUMN < :B;
  forall j in 1 .. (row4del / 100000 + 1)
    delete table
     where rowid in
           (select rowid
              from table
             WHERE NUMBER_COLUMN = :A AND DATE_COLUMN < :B
       and rownum < 100000);
    commit;
end;

Я не понял, это юмор такой несмешной?

Или ты можешь объяснить какую роль здесь выполняет FORALL?
...
Рейтинг: 0 / 0
13.08.2016, 07:36:25
    #39291385
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
Fogelв любом случае вместо loop для своих циклов delete используй forallУ тебя плохо получается выглядеть умным, каждый раз давая такие бредовые советы.
...
Рейтинг: 0 / 0
13.08.2016, 11:11:24
    #39291412
казинак
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
--Eugene--Есть не секционированная таблица в несколько десятков GB.
,...
При этом происходит переполнение UNDO (очевидно, параллельно происходит более другая работа)......
по нынешним временам сотня гигов - это тьфу
просто попроси админов добавить неcколько десятков гигов в undo
и не парься с оптимизацией

а то здешние недогуру тебя с дерьмом смешают
ниче полезного не скажут, но ты узнаешь много нового о своем уровне развития, о благонадежности и здравомыслии своих родственников до седьмого колена,
ну и т.д.

это форум оракл, детка!!!
...
Рейтинг: 0 / 0
13.08.2016, 11:36:32
    #39291417
Nobody1111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
казинакпо нынешним временам сотня гигов - это тьфу
просто попроси админов добавить неcколько десятков гигов в undo

простец
...
Рейтинг: 0 / 0
13.08.2016, 12:54:52
    #39291441
Nobody1111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
--Eugene--Задача состоит в том чтобы понять оптимальное количество записей, которые следует удалять при таком подходе.

Оптимальное количество - это, думаю, между 2 огней:
1) чтобы undo не переполнялся?
2) чтобы сервер слишком частыми коммитами не изнасиловать.

То, что между этими крайностями, - оптимально.
...
Рейтинг: 0 / 0
13.08.2016, 16:33:17
    #39291474
--Eugene--
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
Nobody1111Оптимальное количество - это, думаю, между 2 огней:
1) чтобы undo не переполнялся?
2) чтобы сервер слишком частыми коммитами не изнасиловать.

То, что между этими крайностями, - оптимально.в том-то и дело
Этот диапазон не так уж мал
...
Рейтинг: 0 / 0
13.08.2016, 16:47:40
    #39291475
Оптимальный способ очистки таблицы по критерию
--Eugene--,

Оптимальность определяется:
- уложиться в ресурсы (undo);
- время выполнения;
- время на раздумья.

Если бы послушался первого ответа, то решение было бы на сутки оптимальнее.
...
Рейтинг: 0 / 0
14.08.2016, 12:53:13
    #39291570
orawish
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
--Eugene--,

совершенно согласен с много раз вышеозвученным мнением насчет ресурсов.
ресурсы надо иметь,
но ежели, например, работа-на-раз (быстро сделать и убежать ),
то имейте ввиду метод деления поляны на известное количество статистически-равных частей
например, substr например rowid, например, -1
Код: plsql
1.
substr(rowid,-1)


ну а вокруг этого можно накрутить например и (пещерный;)параллелизм раздачей значений для критериев хвоста сабстра по сессиям
...
Рейтинг: 0 / 0
14.08.2016, 18:01:03
    #39291632
Guest я Guest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
--Eugene--,

> Задача состоит в том чтобы понять оптимальное количество записей, которые следует удалять при таком подходе.

Оптимальное количество = <Сколько UNDO можно использовать> / <UNDO, требуемое на удаление одной записи>

UNDO на удаление записи (в среднем) можно узнать из V$TRANSACTION.USED_UBLK

> Возможно, есть более лучший способ?
Оптимальный способ - не делать таких массовых удалений.
...
Рейтинг: 0 / 0
19.08.2016, 13:37:23
    #39294573
Fogel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
Вячеслав ЛюбомудровFogel--Eugene--,

попробуй ещё так и сравни быстродействие c другими способами
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
declare
  row4del single_integer;
begin
  select count(1)
    into row4del
    from table
   WHERE NUMBER_COLUMN = :A AND DATE_COLUMN < :B;
  forall j in 1 .. (row4del / 100000 + 1)
    delete table
     where rowid in
           (select rowid
              from table
             WHERE NUMBER_COLUMN = :A AND DATE_COLUMN < :B
       and rownum < 100000);
    commit;
end;

Я не понял, это юмор такой несмешной?

Или ты можешь объяснить какую роль здесь выполняет FORALL?

это ум, бегущий впереди рук
а что я имел ввиду, сейчас продемонстрирую.
сегодня как раз потребовалось решить нечто подобное:

дано: таблица без партиций, два индекса.
Нужно удалить все записи с определённых файлов - данное поле без индекса
Замер показал около 7,5 млн строк
Код: plsql
1.
2.
select count(*)  from table
 where regexp_like(file_name, 'блаблабла|блаблабла1|блаблабла2|блаблабла3|блаблабла4|блаблабла5|и ещё столько же');


База - пром, в таблицу что-то льётся не каждую секунду, но раз в 5 минут или чаще.
Оценил вообще размер бедствия по индексированному полю
Код: plsql
1.
2.
select count(*) from table
  where insert_date < sysdate-20; --- 6621339


Кол-во больше (примерно на 0,5 млн), чем по условию имени файлов за то же время, это неправильно, кто-то за собой не чистит. Решил совместить приятное с полезным и вначале пройтись по индексу
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
declare
  type t_cu_rou is table of rowid index by pls_integer;
  col_cu_rou t_cu_rou;
  row4del    pls_integer;
begin
  select count(*)
    into row4del
    from table
   where insert_date < sysdate-20;
  for j in 1 .. (row4del / 100000 + 1) loop
    select rowid bulk collect
      into col_cu_rou
      from table
     where insert_date < sysdate-20
       and rownum < 100000;
    forall k_idx in col_cu_rou.first .. col_cu_rou.last
      delete from table where rowid = col_cu_rou(k_idx);
  end loop;
end;


/
время очистки 498 с
После этого запрос вернул 1,3 млн
Код: plsql
1.
2.
select count(*)  from table
 where regexp_like(file_name, 'блаблабла|блаблабла1|блаблабла2|блаблабла3|блаблабла4|блаблабла5|и ещё столько же'); --- 1339863


В скрипте исправил условие на неиндексируемое.
Удаление заняло 148 с

около года назад тоже нечто подобное делал на этой же таблице
"опытные" товарищи тогда как раз предложили loop c пачками по 10 тыс и коммитом
было около 15 млн строк - удалялось несколько часов, благо в джоб запихнул.

Ах, да, забыл. Размер табличного пространства undo 2 gb

После этого вспомнил про данную тему и решил посмотреть, что тут ещё насоветовали.
Прочитал комментарии и решил поделиться.

ElicУ тебя плохо получается выглядеть умным, каждый раз давая такие бредовые советы.
зато хорошо получается троллить снобов, для которых набор знаний синоним ума.
умные не троллятся, а делают выводы себе на пользу.
ну или не делают, если им не интересно.
...
Рейтинг: 0 / 0
19.08.2016, 14:43:15
    #39294630
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимальный способ очистки таблицы по критерию
Fogel
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
declare
  type t_cu_rou is table of rowid index by pls_integer;
  col_cu_rou t_cu_rou;
  row4del    pls_integer;
begin
  select count(*)
    into row4del
    from table
   where insert_date < sysdate-20;
  for j in 1 .. (row4del / 100000 + 1) loop
    select rowid bulk collect
      into col_cu_rou
      from table
     where insert_date < sysdate-20
       and rownum < 100000;
    forall k_idx in col_cu_rou.first .. col_cu_rou.last
      delete from table where rowid = col_cu_rou(k_idx);
  end loop;
end;

Эх, это уё$ище эквивалентно следующему коду:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
begin
  loop
    delete … rownum < :n;
    exit when sql%rowcount = 0;
  end loop;
end;
/

А с учётом отсутствия фиксации - следующему:
Код: plsql
1.
delete …;

Естественно, более короткая форма эффективнее (вплоть до гораздо) более длинной.

Ты поменьше выпячивай свою альтернативную одарённость. Это выглядит как-то нездорово
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Оптимальный способ очистки таблицы по критерию / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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