Ce face EXPLAIN (ANALYZE, BUFFERS)
Comanda EXPLAIN afișează planul de execuție pe care optimizatorul bazat pe costuri (query planner) din PostgreSQL îl alege pentru o interogare: cum sunt scanate tabelele (Seq Scan, Index Scan, Index Only Scan, Bitmap Heap Scan) și ce algoritm de joncțiune este folosit (Nested Loop, Hash Join, Merge Join).
Când adaugi opțiunea ANALYZE, PostgreSQL execută efectiv interogarea și afișează alături de estimări și valorile reale (actual time, rows, loops). Împreună cu BUFFERS (care arată câte pagini de 8 KB au fost găsite în memoria RAM cache — shared hit — față de cele citite de pe disc — read), EXPLAIN (ANALYZE, BUFFERS) este instrumentul suprem de diagnosticare a interogărilor lente.
Clauze, operatori și argumente
| Clauză / Operator | Descriere |
|---|---|
EXPLAIN interogare |
Afișează doar planul estimat și costurile calculate din statistici, fără a rula interogarea. |
ANALYZE |
Execută interogarea și măsoară timpul real (în milisecunde) și numărul real de rânduri la fiecare pas. |
BUFFERS |
Arată numărul de blocuri de 8 KB citite din memoria partajată (shared hit) sau de pe disc (shared read). |
VERBOSE |
Afișează lista completă de coloane ieșite din fiecare nod al planului și numele complet al obiectelor. |
SETTINGS |
În PostgreSQL 12+, afișează parametrii de configurare non-default care au influențat planificatorul. |
FORMAT TEXT | JSON | YAML |
Specifică formatul de ieșire al planului (FORMAT JSON este folosit de vizualizatoare grafice). |
Exemple
Exemplul 1: Inspectarea unei interogări indexate cu EXPLAIN (ANALYZE, BUFFERS)
Verificăm că interogarea folosește indexul pe (client_id, plasata_la) și că toate paginile vin din memoria RAM (shared hit=4).
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, total_lei, plasata_la
FROM comenzi
WHERE client_id = 101
ORDER BY plasata_la DESC
LIMIT 5;
Rezultat interogare
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.42..8.45 rows=5 width=20) (actual time=0.031..0.036 rows=3 loops=1)
Buffers: shared hit=4
-> Index Scan Backward using idx_comenzi_client_data on comenzi (cost=0.42..24.50 rows=15 width=20) (actual time=0.029..0.034 rows=3 loops=1)
Index Cond: (client_id = 101)
Buffers: shared hit=4
Planning Time: 0.115 ms
Execution Time: 0.058 ms
(7 rows)
Exemplul 2: Testarea în siguranță a unui UPDATE sau DELETE cu EXPLAIN ANALYZE în interiorul unui ROLLBACK
Deoarece EXPLAIN ANALYZE chiar execută comanda, încadrăm un DELETE într-o tranzacție pe care o anulăm cu ROLLBACK.
BEGIN;
EXPLAIN (ANALYZE, BUFFERS)
DELETE FROM sesiuni_active
WHERE expira_la < NOW();
ROLLBACK;
Rezultat interogare
BEGIN
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------
Delete on sesiuni_active (cost=0.29..18.40 rows=120 width=6) (actual time=0.412..0.413 rows=114 loops=1)
Buffers: shared hit=92
-> Index Scan using idx_sesiuni_expira on sesiuni_active (cost=0.29..18.40 rows=120 width=6) (actual time=0.025..0.148 rows=114 loops=1)
Index Cond: (expira_la < now())
Buffers: shared hit=6
Planning Time: 0.084 ms
Execution Time: 0.445 ms
(7 rows)
ROLLBACK
Greșeli frecvente
- Rularea
EXPLAIN ANALYZE DELETE ...sauEXPLAIN ANALYZE UPDATE ...direct în afara unei tranzacții: interogarea chiar va șterge sau modifica rândurile! Pune-o întotdeauna întreBEGIN;șiROLLBACK;. - Ignorarea multiplicatorului
loops=N: timpulactual time=0.05..0.12afișat pe un nod este media per iterație; dacă pe acel nod apareloops=1000, timpul total petrecut acolo este0.12 * 1000 = 120 ms.
Comenzi și funcții înrudite
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.VACUUM și ANALYZE: Recuperează spațiul ocupat de rândurile șterse/modificate (MVCC dead tuples) și actualizează statisticile pentru optimizator.Comenzi psql (\l, \c, \dt, \d, \timing, \copy): Navighează rapid prin baze de date, tabele, scheme și exportă/importă CSV direct din clientul interactiv de terminal psql.