LINUX.ORG.RU

Удаление из большой таблицы без потери constraints

 ,


1

3

Добрый день!

Мне необходимо удалить большую часть таблицы с четырьмя миллионами строк, delete from tbl where работает бесконечность, поэтому, по всей видимости, нужно использовать промежуточные таблицы. Ситуацию осложняют несколько других таблиц, c Foreign-key constraints: ON DELETE SET NULL. И это правило должно выполняться во время удаления.

Если делать

BEGIN;
CREATE TABLE tbl_new AS SELECT * FROM tbl where a is b;           
ALTER TABLE tbl RENAME TO tbl_old;
ALTER TABLE tbl_new RENAME TO tbl;
COMMIT;
drop table tbl_old cascade;
То для сохранения целостности, после переименования tbl в tbl_old postgress меняет и constraints, превращая ссылки в REFERENCES tbl_old(id)

Если делать

BEGIN;
CREATE TABLE tbl_tmp AS SELECT * FROM tbl where a is b          
TRUNCATE tbl;
INSERT INTO cart SELECT * FROM tbl_tmp;
COMMIT;
То pg не деает выполнить TRUNCATE из за ссылок, и предлагат сделать TRUNCATE CASCADE.

Как быть?


Ответ на: комментарий от Sorcerer

Пробовал c разным окном, производительность удручает.

helium ()

может у тебя индексов не хватает?

Rastafarra ★★★★ ()

странно, конечно. Но если ничего не помогает - только «закат солнца вручную»: в транзакции снять «констрэйт»(-ы), возможно и индексы удалить, удалить записи, ручками обнулить поля в связанных таблицах, реиндексировать (если удалял индексы), восстановить «констрэйт»(-ы)

Но мне кажется, что что-то там у тебя не так...

yyk ★★★★★ ()
Ответ на: комментарий от vtVitus

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

helium ()

Ответь себе на вопросы:

1. Сколько времени работает запрос на удаление одной записи и если долго, то нет ли проблем с отсутствующими индексами.

2. Попробуй удалять по 100, но коммит после каждой порции, при отсутствии других пользователей.

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

Дисклеймер: я не знаток PG.

den73 ★★★★★ ()
Ответ на: комментарий от helium

Миллионы строк - не так уж и много, а тут какой-то странный затык.

Хочешь реальной помощи: выкладывай структуру БД (той её части, которая зависит от очищаемой таблицы или связана с ней) и настройки pg - тогда может и будут реальные советы.

yyk ★★★★★ ()

Как уже выше написали, у тебя индексов нет для быстрой проверки FK, удаляя «четыре миллиона строк» с FK ты делаешь 4 миллиона Seq scan'ов каждой дочерней таблицы для ON DELETE SET NULL.

anonymous ()
Ответ на: комментарий от anonymous

Да, и 4 миллиона index scan'ов * N дочерних таблиц — на обычном домашнем диске это очень медленно.

anonymous ()
Ответ на: комментарий от anonymous

Как правило в таких случаях при наличии индексов это все достаточно быстро делается, даже на «обычном домашне диске»

no-dashi ★★★★★ ()

А в pg разве нету чего-то типа SET FOREIGN_KEY_CHECKS = 0?

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

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

Stanson ★★★★★ ()
Последнее исправление: Stanson (всего исправлений: 1 )

delete тормозит изза того что он генерит логи видимо нужно как-то так create table newtbl like oldtbl; insert into newtbl from oldtbl; drop oldtbl; rename newtbl ...

drsm ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.