DELETE … USING și TRUNCATE în PostgreSQL

Modificare date și tranzacții PostgreSQL 8.1+ (standard în PostgreSQL 15–17)

Șterge rânduri filtrate prin joncțiuni cu DELETE ... USING sau golește instantaneu tabele întregi cu TRUNCATE.

Sintaxă SQL
DELETE FROM tabel_tinta t USING tabel_sursa s WHERE t.id = s.id RETURNING t.id;nTRUNCATE TABLE tabel RESTART IDENTITY CASCADE;

Ce face DELETE ... USING și TRUNCATE

Pentru ștergerea selectivă a rândurilor pe baza unei condiții care implică un alt tabel, PostgreSQL oferă clauza DELETE FROM tabel USING alt_tabel WHERE ... (echivalentul lui UPDATE ... FROM). La fel ca la INSERT și UPDATE, poți adăuga RETURNING pentru a vedea sau arhiva exact rândurile șterse.

Când vrei să golești complet unul sau mai multe tabele mari, comanda TRUNCATE este de mii de ori mai rapidă decât DELETE FROM tabel, deoarece eliberează direct fișierele de stocare de pe disc fără să scaneze rând cu rând și fără să lase tupluri moarte pentru VACUUM. În PostgreSQL, chiar și TRUNCATE este tranzacțional (poate fi anulat cu ROLLBACK dacă rulează într-un bloc BEGIN).

Clauze, operatori și argumente

Clauză / Operator Descriere
DELETE FROM tabel [AS t] Șterge rândurile din tabelul specificat care îndeplinesc condiția din WHERE.
USING tabel_sursa [AS s] Introduce tabele suplimentare pentru a filtra rândurile de șters prin joncțiune în WHERE.
RETURNING * Returnează rândurile care tocmai au fost șterse.
TRUNCATE [TABLE] tabel Golește instantaneu tabelul de toate rândurile, eliberând imediat spațiul pe disc.
RESTART IDENTITY Opțiune pentru TRUNCATE care resetează automat secvențele asociate coloanelor SERIAL sau IDENTITY înapoi la 1.
CASCADE Opțiune pentru TRUNCATE care golește și tabelele dependente prin chei străine (FOREIGN KEY).

Exemple

Exemplul 1: Ștergerea sesiunilor utilizatorilor dezactivați cu DELETE … USING

Eliminăm din tabelul sesiuni_active toate sesiunile care aparțin utilizatorilor marcați ca blocat în tabelul utilizatori.

DELETE FROM sesiuni_active s
USING utilizatori u
WHERE s.utilizator_id = u.id
  AND u.blocat = true
RETURNING s.token_id, u.email;

Rezultat interogare

   token_id   |        email         
--------------+----------------------
 tok_98a1f2c0 | cont.spam@exemplu.ro
 tok_44b7e1d9 | cont.spam@exemplu.ro
(2 rows)

DELETE 2

Exemplul 2: Golirea rapidă a unui tabel de staging și resetarea ID-urilor cu TRUNCATE

Golim tabelul import_staging și repornim contorul coloanei de identitate de la 1.

TRUNCATE TABLE import_staging RESTART IDENTITY;

Rezultat interogare

TRUNCATE TABLE

Greșeli frecvente

  • Atenție la TRUNCATE ... CASCADE: acesta va goli complet toate tabelele care au o cheie străină către tabelul țintă, chiar dacă acele chei străine nu au fost definite cu ON DELETE CASCADE.
  • Reține că TRUNCATE nu declanșează triggerele ON DELETE FOR EACH ROW și necesită un lacăt exclusiv ACCESS EXCLUSIVE pe tabel.

Comenzi și funcții înrudite

  • UPDATE ... FROM: Actualizează rândurile unui tabel folosind date dintr-un alt tabel sau dintr-o listă VALUES prin clauza FROM.
  • BEGIN, COMMIT, ROLLBACK și SAVEPOINT: Controlează tranzacțiile ACID și punctele intermediare de salvare (SAVEPOINT) pentru recuperarea din erori.
  • VACUUM și ANALYZE: Recuperează spațiul ocupat de rândurile șterse/modificate (MVCC dead tuples) și actualizează statisticile pentru optimizator.