Пожалуйста, порекомендуйте лучший вариант массового удаления - PullRequest
1 голос
/ 17 ноября 2011

Я использую PostgreSQL 8.1.4.У меня есть 3 таблицы: одна является ядром (таблица 1), другие являются зависимыми (таблица 2, таблица 3).Я вставил 70000 записей в таблицу 1 и соответствующие записи в других 2 таблицах.Поскольку я использовал CASCADE, я мог удалить связанные записи, используя DELETE FROM table1;Он отлично работает, когда записи минимальны в моей текущей версии PostgreSQL.Когда у меня огромный объем записей, он пытается удалить все, но в течение многих часов нет признаков прогресса!Принимая во внимание, что оптовый импорт, делает в течение нескольких минут.Я хочу сделать массовое удаление в разумные минуты.Я попробовал TRUNCATE также.Как, TRUNCATE table3, table2, table1;Никаких изменений в производительности, хотя.Это займет больше времени и никаких признаков завершения!Из сети я получил несколько опций, например, удалив все ограничения и затем воссоздав их.Но ни один запрос не может быть успешно выполнен над таблицей, когда загружено больше данных!Пожалуйста, порекомендуйте мне лучшие решения для удаления всех записей в считанные минуты.

CREATE TABLE table1(
        t1_id   SERIAL PRIMARY KEY,
        disp_name       TEXT NOT NULL DEFAULT '',
        last_updated TIMESTAMP NOT NULL DEFAULT current_timestamp,
        UNIQUE(disp_name)
    ) WITHOUT OIDS;

CREATE UNIQUE INDEX disp_name_index on table1(upper(disp_name));

CREATE TABLE table2 (
        t2_id           SERIAL PRIMARY KEY,
        t1_id   INTEGER REFERENCES table1 ON DELETE CASCADE,
        type    TEXT
    ) WITHOUT OIDS;

CREATE TABLE table3 (
        t3_id           SERIAL PRIMARY KEY,
        t1_id   INTEGER REFERENCES table1 ON DELETE CASCADE,
        config_key      TEXT,
        config_value    TEXT
    ) WITHOUT OIDS;

С уважением, Шива.

Ответы [ 3 ]

2 голосов
/ 17 ноября 2011

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

в таблице 2 создать индекс для столбца t1_id

в таблице 3 создать индекс для t1_idстолбец

, который должен немного ускорить процесс.

И / или, не беспокойтесь о on delete cascade, создайте хранимую процедуру удаления, которая сначала удаляет из дочерних таблиц, а затем изродительской таблицы, это может быть быстрее, чем позволить postgresql сделать это за вас.

0 голосов
/ 17 ноября 2011

Держу пари, что вам не хватает некоторых индексов в базе данных.

Если вы выполните команду удаления из консоли psql, просто нажмите Ctrl-C - транзакция будет прервана, и psql должен сообщить вам, какой запрос выполнялся, когда вы его прервали.

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

У меня недавно была похожая ситуация, и добавление индекса решило проблему.

0 голосов
/ 17 ноября 2011

В SQL оператор TRUNCATE TABLE является языком определения данных (DDL) операция, которая отмечает экстенты таблицы для освобождения (пусто для повторного использования). Результат этой операции быстро удаляет все данные из таблицы , как правило, в обход ряда целостности исполнительные механизмы . http://en.wikipedia.org/wiki/Truncate_(SQL)

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

Чтобы решить эту проблему, вы должны проверить ваши активные транзакции в вашей базе данных. Самый простой способ (по крайней мере под SQL Server, это работает) - написать «ROLLBACK COMMIT;» в окно запроса и выполните его. Если он выполняется без выдачи ошибки, это означает, что фактически была активная транзакция. Если активной транзакции не осталось, появится сообщение об ошибке.

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