PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Най-добрият начин да изтриете милиони редове по ID

Всичко зависи...

  • Ако приемем, че няма едновременен достъп за запис до включени маси или може да се наложи да заключите маси изключително или този маршрут може изобщо да не е за вас.

  • Изтрийте всички индекси (евентуално с изключение на необходимите за самото изтриване).
    Създайте ги отново след това. Това обикновено е много по-бързо от постепенните актуализации на индексите.

  • Проверете дали имате тригери, които могат безопасно да бъдат изтрити/деактивирани временно.

  • Външните ключове препращат ли към вашата таблица? Могат ли да бъдат изтрити? Временно изтрит?

  • В зависимост от настройките ви за автоматично вакуумиране може помогнете за стартиране на 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 тригери, които може да съществуват за таблиците.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SELECT или INSERT ред в една команда

  2. Как Extract() работи в PostgreSQL

  3. Промяна на типа данни на колона на сериен

  4. Как работи current_timestamp() в PostgreSQL

  5. Защо Postgres казва, че колоната не съществува?