Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Удалить много строк из одиночной таблицы  [new]
Alibek B.
Member

Откуда:
Сообщений: 3313
Есть таблица, в которой хранится примерно 6М строк.
create table flags (
  flag_id number not null,
  account_id number not null,
  status varchar2 not null,
  moment datetime not null,
  review datetime
)

Таблица минимально связана с БД, в ней есть один FK (account_id).
БД используется периодической процедурой на одном сервере (то есть конкурентного доступа к ней быть не должно), процедура читает записи с moment>:date, а затем делает update set review=sysdate для обработанных записей (построчно). Обработанные записи более нигде не используются. Сейчас я хочу их удалить, это примерно 5М строк.
delete from flags where moment < date'2019-01-01' выполняется уже почти 10 минут.
С данной таблицей уже просто дождусь окончания удаления, но кроме нее у меня есть еще пара подобных таблиц, в которых суммарно под 20М записей.
Как лучше всего удалять большие объемы записей в подобных случаях?

Сообщение было отредактировано: 7 ноя 19, 15:10
7 ноя 19, 15:08    [22011601]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 17717
CTAS +права+индексы+ограничения c последующими drop+rename
Insert select в partitioned таблицу идентичной структуры c последующим exchange partition если зачищаемая таблица не секционирована, иначе в посекционно в несекционированную c обратным обменом
7 ноя 19, 15:15    [22011605]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 17717
Вариация первого варианта: CTAS + truncate исходной + обратный insert select
7 ноя 19, 15:17    [22011606]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
Alibek B.
Member

Откуда:
Сообщений: 3313
andrey_anonymous
CTAS +права+индексы+ограничения c последующими drop+rename

Слишком брутально для меня, лучше подожду лишний десяток минут.

andrey_anonymous
Вариация первого варианта: CTAS + truncate исходной + обратный insert select

Это выглядит более понятно.
Но наверное на время последнего шага процедура на сервере работать не будет?
7 ноя 19, 15:34    [22011617]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 17717
Alibek B.
на время последнего шага процедура на сервере работать не будет?

Так Вам еще и в online?
Тогда dbms_redefinition.
Ну и если подобные развлечения планируются в будущем, то рассмотрите жизненный цикл данных и предусмотрите решение - хотя бы partitioned table
7 ноя 19, 15:38    [22011621]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
-2-
Member

Откуда:
Сообщений: 14995
andrey_anonymous
CTAS +права+индексы+ограничения c последующими drop+rename
ATMIR/ui
7 ноя 19, 15:52    [22011641]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
Synoptic
Member

Откуда:
Сообщений: 103
1. Создаём индекс по полю, по которому будет отсечка.
2. Формируем коллекцию rowid строк, подлежащих удалению.
3. forall ...delete.
8 ноя 19, 17:45    [22012528]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 17717
Synoptic
1. Создаём индекс по полю, по которому будет отсечка.
2. Формируем коллекцию rowid строк, подлежащих удалению.
3. forall ...delete.

Доп. расходы (просканировать таблицу, создать индекс, просканировать индекс, сложить 100500 rowid в коллекцию, потратить ресурсы на обновление индекса при удалении из таблицы) вижу.
На чем предполагаете выигрыш?
8 ноя 19, 17:48    [22012532]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
Valergrad
Member

Откуда:
Сообщений: 686
Если нужно удалить намного больше строк чем оставить, то может оказаться проще всего:

1. Создать пустую копию таблицы со всеми ключами-индексами и т.п.
2. Insert /*+ append parallel(16) */ into table_2 as select * from table_1 то что нужно оставить.
3. Сделать rename новой таблицы на старую, ну и имена индексов-ключей поменять.

Время недоступности для чтения минимально. Но если в нее параллельно пишут - этот способ не подойдет.
8 ноя 19, 20:35    [22012598]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
Synoptic
Member

Откуда:
Сообщений: 103
andrey_anonymous
Synoptic
1. Создаём индекс по полю, по которому будет отсечка.
2. Формируем коллекцию rowid строк, подлежащих удалению.
3. forall ...delete.

Доп. расходы (просканировать таблицу, создать индекс, просканировать индекс, сложить 100500 rowid в коллекцию, потратить ресурсы на обновление индекса при удалении из таблицы) вижу.
На чем предполагаете выигрыш?
Индекс создаём один раз (или это разовая задача?)
Плюс не развалятся пакеты при drop/rename таблиц, которые их используют.
Плюс таблицы полностью доступны, т.е. это online-операция.
Ну и кроме того, получим нормальный PL/SQL скрипт, без всякого DDL внутри.

Сообщение было отредактировано: 9 ноя 19, 06:39
9 ноя 19, 06:37    [22012660]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
Alibek B.
Member

Откуда:
Сообщений: 3313
Synoptic
1. Создаём индекс по полю, по которому будет отсечка.
2. Формируем коллекцию rowid строк, подлежащих удалению.
3. forall ...delete.

Нужно будет подумать.
Индекс по полю moment уже есть.
Но вот с пунктом 2 мне кажется неоднозначно.
Нужно ведь куда-то сложить 5 миллионов rowid? Если в память, то не скажется ли это негативно на сервере? Если во временную таблицу, то не получится шило на мыло?
9 ноя 19, 12:05    [22012717]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
Misha111
Member

Откуда:
Сообщений: 12
я так понимаю Synoptic имел ввиду удаление небольшими (сравнительно) порциями
9 ноя 19, 13:50    [22012744]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 29406
Alibek B.
Нужно ведь куда-то сложить 5 миллионов rowid? Если в память, то не скажется ли это негативно на сервере? Если во временную таблицу, то не получится шило на мыло?
А ты пробуй. Не зря ж говорят, что если тебя @бут, то ты крепчаешь. Со временем, хотя за лет 10 это уже должно было произойти, научишься думать своей головой и не реагировать на всяких выскочек.
9 ноя 19, 15:15    [22012776]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
Synoptic
Member

Откуда:
Сообщений: 103
Alibek B.,


Alibek B.
Synoptic
1. Создаём индекс по полю, по которому будет отсечка.
2. Формируем коллекцию rowid строк, подлежащих удалению.
3. forall ...delete.

Нужно будет подумать.
Индекс по полю moment уже есть.
Но вот с пунктом 2 мне кажется неоднозначно.
Нужно ведь куда-то сложить 5 миллионов rowid? Если в память, то не скажется ли это негативно на сервере? Если во временную таблицу, то не получится шило на мыло?
Не далее как на текущей неделе удалял порядка 10 Млн записей из высоконагруженных таблиц, с количеством записей исчисляемых миллиардами. Ничего не просело, и таблицы всё это время были доступны.
Железо, на котором работает база - 2Тб ОЗУ, 128 процессорных ядер.
Делать же подмену таблиц на проде...даже не знаю, жесть какая-то.
9 ноя 19, 20:13    [22012862]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
-2-
Member

Откуда:
Сообщений: 14995
Alibek B.
таблиц, в которых суммарно под 20М записей.
Synoptic
таблиц, с количеством записей исчисляемых миллиардами.
Ну раз с миллиардами не просело, решение очевидно - добить количество строк до беспроблемного.
10 ноя 19, 12:52    [22012982]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
Alibek B.
Member

Откуда:
Сообщений: 3313
Synoptic
Железо, на котором работает база - 2Тб ОЗУ, 128 процессорных ядер.

У меня 4 ядра и 4ГБ ОЗУ.
10 ноя 19, 13:27    [22012996]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 2017
Alibek B.
Synoptic
Железо, на котором работает база - 2Тб ОЗУ, 128 процессорных ядер.

У меня 4 ядра и 4ГБ ОЗУ.


автор
delete from flags where moment < date'2019-01-01' выполняется уже почти 10 минут.


удаляйте по старинке, и не заморавчивайте себе голову
10 +/- минут (для миллионов строк ето фигня)

зы
я удалял порциями в цикле прімерно по 100 000 (and rownum<100000) + коммит (порции подобрал емперически)

.....
stax
11 ноя 19, 11:15    [22013349]     Ответить | Цитировать Сообщить модератору
 Re: Удалить много строк из одиночной таблицы  [new]
Alibek B.
Member

Откуда:
Сообщений: 3313
Да, я так и понял.
Правда в моем случае разбивать на порции можно не через rownum, а напрямую с использованием поля moment, т.к. оно все равно индексирован.
То есть
delete from flags where moment < date'2015-01-01';
delete from flags where moment < date'2016-01-01';
delete from flags where moment < date'2017-01-01';
delete from flags where moment < date'2018-01-01';
delete from flags where moment < date'2019-01-01';
11 ноя 19, 12:23    [22013419]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить