Ce face VACUUM și ANALYZE
Datorită arhitecturii MVCC (Multi-Version Concurrency Control) din PostgreSQL, comenzile DELETE și UPDATE nu șterg fizic pe loc rândurile vechi de pe disc, ci le marchează drept „tupluri moarte” (dead tuples) pentru ca tranzacțiile concurente să poată citi în continuare o imagine consistentă. Comanda VACUUM curăță aceste tupluri moarte și marchează spațiul ca reutilizabil pentru viitoarele inserări și actualizări, actualizând totodată și Visibility Map (esențială pentru Index-Only Scans).
Comanda ANALYZE scanează un eșantion din tabel și actualizează statisticile interne (distribuția valorilor, cardinalitatea, histogramele) pe care le folosește EXPLAIN pentru a alege cel mai bun plan de execuție. Deși daemonul autovacuum rulează automat în fundal, rularea manuală a lui VACUUM (ANALYZE) este foarte utilă imediat după importuri, actualizări sau ștergeri masive.
Clauze, operatori și argumente
| Clauză / Operator | Descriere |
|---|---|
VACUUM tabel |
Eliberează și refolosește intern spațiul ocupat de tuplurile moarte fără a bloca citirile și scrierile pe tabel. |
ANALYZE tabel |
Colectează statistici actualizate despre distribuția datelor din tabel pentru optimizatorul de interogări. |
VACUUM (ANALYZE) tabel |
Execută atât curățarea MVCC, cât și actualizarea statisticilor într-o singură comandă. |
VERBOSE |
Afișează un raport detaliat cu numărul de pagini și tupluri moarte eliminate. |
VACUUM FULL tabel |
Rescrie complet tabelul într-un fișier nou pe disc pentru a ceda spațiul înapoi sistemului de operare, dar blochează exclusiv tabelul! |
Exemple
Exemplul 1: Curățarea tuplurilor moarte și actualizarea statisticilor după un import masiv
Rulăm VACUUM (VERBOSE, ANALYZE) pe tabelul comenzi fără a întrerupe traficul aplicației.
VACUUM (VERBOSE, ANALYZE) comenzi;
Rezultat interogare
INFO: vacuuming "public.comenzi"
INFO: finished vacuuming "public.comenzi": index scans: 1
pages: 0 removed, 842 remain, 128 scanned (15.20% of total)
tuples: 1420 removed, 48510 remain, 0 are dead but not yet removable
INFO: analyzing "public.comenzi"
INFO: "comenzi": scanned 842 of 842 pages, containing 48510 live rows and 0 dead rows
VACUUM
Exemplul 2: Verificarea tabelelor cu multe tupluri moarte (bloat) în pg_stat_user_tables
Interogăm vederea de sistem pg_stat_user_tables pentru a vedea numărul de rânduri vii, rânduri moarte și momentul ultimului autovacuum.
SELECT relname AS tabel,
n_live_tup AS randuri_vii,
n_dead_tup AS randuri_moarte,
last_autovacuum::timestamp(0) AS ultimul_autovacuum,
last_autoanalyze::timestamp(0) AS ultimul_autoanalyze
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 3;
Rezultat interogare
tabel | randuri_vii | randuri_moarte | ultimul_autovacuum | ultimul_autoanalyze
----------------+-------------+----------------+---------------------+---------------------
sesiuni_active | 12400 | 1850 | 2025-03-20 09:40:12 | 2025-03-20 09:40:13
comenzi | 48510 | 42 | 2025-03-20 08:15:00 | 2025-03-20 10:25:01
produse | 1250 | 5 | 2025-03-19 22:10:44 | 2025-03-19 22:10:45
(3 rows)
Greșeli frecvente
- Rularea
VACUUM FULLîn timpul orelor de vârf: spre deosebire deVACUUMstandard (care rulează online),VACUUM FULLpune un lacătACCESS EXCLUSIVE(blochează inclusiv simplele interogăriSELECT!) și necesită temporar spațiu liber pe disc egal cu dimensiunea tabelului. - Neexecutarea unui
ANALYZE tabelimediat după ce ai încărcat sute de mii de rânduri într-un tabel gol: până când ruleazăautoanalyze, optimizatorul poate crede că tabelul are încă 0 rânduri și va alege planuri de execuție ineficiente.
Comenzi și funcții înrudite
EXPLAIN (ANALYZE, BUFFERS): Afișează planul de execuție al optimizatorului, timpii reali pe fiecare nod și blocurile de memorie citite.CREATE INDEX (B-Tree, GIN, Partial, CONCURRENTLY): Creează indecși B-Tree, GIN (pentru JSONB și Array), indecși parțiali (WHERE) și indecși pe expresii fără blocarea scrierilor.DELETE ... USING și TRUNCATE: Șterge rânduri filtrate prin joncțiuni cu DELETE … USING sau golește instantaneu tabele întregi cu TRUNCATE.