Počnite s planom upita, zatim ispravite najveću cijenu. Koristite EXPLAIN/ da vidite što baza podataka zapravo radi, dodajte prave , uklonite upite, i odaberite samo podatke koji vam trebaju.
Počnite s planom upita, zatim ispravite najveću cijenu. Koristite EXPLAIN/ da vidite što baza podataka zapravo radi, dodajte prave , uklonite upite, i odaberite samo podatke koji vam trebaju.
EXPLAIN ANALYZEEXPLAIN ANALYZE pokazuje plan izvršavanja i stvarno trajanje. Seq Scan preko velike tablice je klasičan crveni signali:
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!
Indeks pretvara potpuno skeniranje u brzu pretragu:
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
Indexi imaju cijenu pri pisanju: svaki INSERT/UPDATE mora također ažurirati indeks, pa indeksirajte stupce na kojima filtrirate/spojite/sortirate — ne svaki stupac. Složeni indeks (customer_id, created_at) služi WHERE customer_id = ? ORDER BY created_at u jednoj strukturi.
N+1 problem — jedan upit za listu, zatim jedan po retku — je vodeći uzrok spora. Zamijenite ga s eager loading, JOIN, ili batch IN (...):
-- 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;
Također odaberite samo potrebne stupce (izbjegavajte SELECT *) i paginirajte s LIMIT/keyset pagination da nikad ne učitate milijune redaka.
Baza podataka je najčešće usko grlo. Čitanje plana vam govori zašto je upit spor umjesto da pogađate; pravi indeks, uklanjanje N+1 i trimiranje skupa rezultata redovito pretvaraju upite od nekoliko sekundi u milisekunde — bez skaliranja hardvera.