Aloita kyselysuunnitelmasta, korjaa sitten suurin kustannus. Käytä EXPLAIN/ nähdäksesi mitä tietokanta todella tekee, lisää oikeat , poista kyselyt ja valitse vain tarvitsemasi data.
Aloita kyselysuunnitelmasta, korjaa sitten suurin kustannus. Käytä EXPLAIN/ nähdäksesi mitä tietokanta todella tekee, lisää oikeat , poista kyselyt ja valitse vain tarvitsemasi data.
EXPLAIN ANALYZEEXPLAIN ANALYZE näyttää suoritussuunnitelman ja todelliset ajat. Seq Scan suuren taulukon yli on klassinen varoitusmerkki:
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!
Indeksi muuttaa täyden skannauksen nopeaksi hakuun:
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
Indekseillä on kustannus kirjoituksissa: jokainen INSERT/UPDATE täytyy päivittää indeksin myös, joten indeksoi sarakkeita joilla suodatat/liität/lajittelet — eivät jokaista saraketta. Yhdistetty indeksi (customer_id, created_at) palvelee WHERE customer_id = ? ORDER BY created_at yhdessä rakenteessa.
N+1 ongelma — yksi kysely listalle, sitten yksi per rivi — on huomattava hitauden syy. Korvaa se eager loadingilla, JOIN:lla tai erillisellä 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;
Myös valitse vain tarvittavat sarakkeet (vältä SELECT *) ja jaottele LIMIT:lla/keyset paginaatiolla jotta et koskaan lataa miljoonia rivejä.
Tietokanta on yleisin pullonkaula. Suunnitelman lukeminen kertoo sinulle miksi kysely on hidas arvaileun sijaan; oikea indeksi, N+1 poistaminen ja tulosjoukkon karsiminen muuttavat rutiininomaisesti sekunteja kestävät kyselyt millisekuntisiksi — ilman laitteiston laajentamista.