Zacznij od planu zapytania, a następnie napraw największy koszt. Użyj /, aby zobaczyć, co baza danych faktycznie robi, dodaj odpowiednie , wyeliminuj zapytania i wybieraj tylko dane, które potrzebujesz.
Zacznij od planu zapytania, a następnie napraw największy koszt. Użyj /, aby zobaczyć, co baza danych faktycznie robi, dodaj odpowiednie , wyeliminuj zapytania i wybieraj tylko dane, które potrzebujesz.
EXPLAINEXPLAIN ANALYZEEXPLAIN ANALYZE pokazuje plan wykonania i rzeczywiste czasy. Seq Scan na dużej tabeli to klasyczna czerwona flaga:
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 zamienia pełne skanowanie w szybkie wyszukiwanie:
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
Indeksy mają koszt przy zapisach: każdy INSERT/UPDATE musi również zaktualizować indeks, więc indeksuj kolumny, na które filtrujesz/dołączasz/sortujesz — nie każdą kolumnę. Złożony indeks (customer_id, created_at) obsługuje WHERE customer_id = ? ORDER BY created_at w jednej strukturze.
Problem N+1 — jedno zapytanie do listy, następnie jedno na wiersz — jest częstą przyczyną powolności. Zastąp go eager loading, JOIN lub grupowanym 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;
Także wybieraj tylko potrzebne kolumny (unikaj SELECT *) i paginuj za pomocą LIMIT/keyset pagination, aby nigdy nie ładować milionów wierszy.
Baza danych to najczęstsza wąskie gardło. Przeczytanie planu mówi ci dlaczego zapytanie jest powolne zamiast zgadywać; właściwy indeks, usunięcie N+1 i przycięcie zestawu wyników rutynowo zamieniają zapytania trwające sekundy na milisekundy — bez skalowania sprzętu.