sql >> Database teknologi >  >> RDS >> PostgreSQL

Bedste måde at slette millioner af rækker efter ID

Det hele afhænger ...

  • Forudsat ingen samtidig skriveadgang til involverede borde, eller du skal muligvis udelukkende låse borde, ellers er denne rute måske slet ikke noget for dig.

  • Slet alle indekser (evt. undtagen dem, der er nødvendige for selve sletningen).
    Genopret dem bagefter. Det er typisk meget hurtigere end trinvise opdateringer af indekser.

  • Tjek, om du har triggere, der sikkert kan slettes/deaktiveres midlertidigt.

  • Refererer fremmednøgler til din tabel? Kan de slettes? Slettet midlertidigt?

  • Afhængigt af dine autovakuumindstillinger kan det hjælp til at køre VACUUM ANALYZE før operationen.

  • Nogle af punkterne, der er anført i det relaterede kapitel i manualen Populering af en database kan også være til nytte, afhængigt af din opsætning.

  • Hvis du sletter store dele af bordet, og resten passer ind i RAM, kan den hurtigste og nemmeste måde være denne:

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;

På denne måde behøver du ikke at genskabe visninger, fremmednøgler eller andre afhængige objekter. Og du får et uberørt (sorteret) bord uden oppustethed.

Læs om temp_buffers indstilling i manualen. Denne metode er hurtig, så længe bordet passer ind i hukommelsen, eller i det mindste det meste af det. Transaktionsindpakningen beskytter mod at miste data, hvis din server går ned midt i denne operation.

Kør VACUUM ANALYZE bagefter. Eller VACUUM FULL ANALYZE hvis du ønsker at bringe den til minimum størrelse (tager eksklusiv lås). For store tabeller overveje alternativerne CLUSTER / pg_repack eller lignende:

  • Optimer Postgres tidsstempelforespørgselsinterval

For små tabeller, en simpel DELETE i stedet for TRUNCATE er ofte hurtigere:

DELETE FROM tbl t
USING  del_list d
WHERE  t.id = d.id;

Læs Bemærkningerne sektion for TRUNCATE i manualen. Især (som Pedro også påpegede i sin kommentar):

TRUNCATE kan ikke bruges på en tabel, der har fremmednøglereferencer fra andre tabeller, medmindre alle sådanne tabeller også afkortes i den samme kommando. [...]

Og:

TRUNCATE vil ikke udløse nogen ON DELETE triggere, der kan eksistere for tabellerne.



  1. Sådan installeres phpMyAdmin på administrerede hostingkonti

  2. Datasikkerhedsstyring

  3. Markørbaserede poster i PostgreSQL

  4. Eksporter data fra en MySQL-database