Всичко зависи...
-
Ако приемем, че няма едновременен достъп за запис до включени маси или може да се наложи да заключите маси изключително или този маршрут може изобщо да не е за вас.
-
Изтрийте всички индекси (евентуално с изключение на необходимите за самото изтриване).
Създайте ги отново след това. Това обикновено е много по-бързо от постепенните актуализации на индексите. -
Проверете дали имате тригери, които могат безопасно да бъдат изтрити/деактивирани временно.
-
Външните ключове препращат ли към вашата таблица? Могат ли да бъдат изтрити? Временно изтрит?
-
В зависимост от настройките ви за автоматично вакуумиране може помогнете за стартиране на
VACUUM ANALYZE
преди операцията. -
Някои от точките, изброени в съответната глава на ръководството Попълване на база данни може също да бъде от полза, в зависимост от вашата настройка.
-
Ако изтриете големи части от таблицата и останалата част се побира в RAM, най-бързият и лесен начин може да бъде следният:
BEGIN; -- typically faster and safer wrapped in a single transaction
SET LOCAL temp_buffers = '1000MB'; -- enough to hold the temp table
CREATE TEMP TABLE tmp AS
SELECT t.*
FROM tbl t
LEFT JOIN del_list d USING (id)
WHERE d.id IS NULL; -- copy surviving rows into temporary table
TRUNCATE tbl; -- empty table - truncate is very fast for big tables
INSERT INTO tbl
SELECT * FROM tmp; -- insert back surviving rows.
-- ORDER BY ? -- optionally order favorably while being at it
COMMIT;
По този начин не е нужно да пресъздавате изгледи, външни ключове или други зависими обекти. И получавате чиста (подредена) маса без подуване.
Прочетете за temp_buffers
настройка в ръководството. Този метод е бърз, стига таблицата да се побере в паметта или поне по-голямата част от нея. Обвивката на транзакциите защитава срещу загуба на данни, ако сървърът ви се срине по средата на тази операция.
Стартирайте VACUUM ANALYZE
след това. Или VACUUM FULL ANALYZE
ако искате да го приведете до минимален размер (отнема изключителна ключалка). За големи таблици помислете за алтернативите CLUSTER
/ pg_repack
или подобен:
- Оптимизиране на обхвата на заявки за времеви печати в Postgres
За малки таблици просто DELETE
вместо TRUNCATE
често е по-бързо:
DELETE FROM tbl t
USING del_list d
WHERE t.id = d.id;
Прочетете Бележки раздел за TRUNCATE
в ръководството. По-специално (както Педро също посочи в коментара си):
TRUNCATE
не може да се използва върху таблица, която има препратки към чужди ключове от други таблици, освен ако всички такива таблици също не са съкратени в същата команда. [...]
И:
TRUNCATE
няма да задействаON DELETE
тригери, които може да съществуват за таблиците.