Începe cu planul de interogare, apoi remediază cel mai mare cost. Folosește / pentru a vedea ce face cu adevărat baza de date, adaugă corecți, elimină interogările și selectează doar datele de care ai nevoie.
Începe cu planul de interogare, apoi remediază cel mai mare cost. Folosește / pentru a vedea ce face cu adevărat baza de date, adaugă corecți, elimină interogările și selectează doar datele de care ai nevoie.
EXPLAINEXPLAIN ANALYZEEXPLAIN ANALYZE arată planul de execuție și cronometrajele reale. O Seq Scan pe o tabel mare este semnalul de alarmă clasic:
EXPLAIN ANALYZE
SELECT * FROM orders WHERE customer_id = 42;
-- Seq Scan on orders (cost=0.00..18500 rows=120)
-- Filter: (customer_id = 42)
-- rows removed by filter: 999880 ← scanned the whole table!
Un indice transformă o scanare completă într-o căutare rapidă:
CREATE INDEX idx_orders_customer ON orders (customer_id);
-- Now: Index Scan using idx_orders_customer (cost=0.42..8.5 rows=120)
-- 1,000,000-row scan → ~120-row lookup
Indicii au un cost la scrieri: fiecare INSERT/UPDATE trebuie să actualizeze și indexul, deci indexează coloanele pe care le filtrezi/unești/sortezi — nu fiecare coloană. Un indice compozit (customer_id, created_at) satisface WHERE customer_id = ? ORDER BY created_at într-o singură structură.
Problema N+1 — o interogare pentru o listă, apoi una pe rând — este o cauză principală a lentoririi. Înlocuiește-o cu eager loading, un JOIN sau IN (...) în lot:
-- N+1: 1 + 100 queries
SELECT * FROM orders; -- then per order: SELECT * FROM users WHERE id = ?
-- Fixed: one JOIN, only needed columns
SELECT o.id, o.total, u.name
FROM orders o JOIN users u ON u.id = o.user_id;
De asemenea, selectează doar coloanele necesare (evită SELECT *) și pagineaza cu LIMIT/keyset pagination pentru a nu încărca niciodată milioane de rânduri.
Baza de date este cel mai obișnuit gât de sticla. Citirea planului îți spune de ce o interogare este lentă în loc să ghicești; indicele corect, eliminarea N+1 și reducerea setului de rezultate transformă în mod obișnuit interogările de lungă durată în milisecunde — fără a scala hardware-ul.