Börja med frågeplan, fixa sedan den största kostnaden. Använd EXPLAIN/ för att se vad databasen faktiskt gör, lägg till rätt , eliminera frågor och välj bara den data du behöver.
Börja med frågeplan, fixa sedan den största kostnaden. Använd EXPLAIN/ för att se vad databasen faktiskt gör, lägg till rätt , eliminera frågor och välj bara den data du behöver.
EXPLAIN ANALYZEEXPLAIN ANALYZE visar exekveringsplan och verklig timing. En Seq Scan över en stor tabell är klassiska röda flaggan:
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!
Ett index förvandlar en full scan till en snabb sökning:
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
Index har en kostnad på skrivningar: varje INSERT/UPDATE måste också uppdatera indexet, så indexera de kolumner du filtrerar/joinnar/sorterar på — inte varje kolumn. Ett sammansatt index (customer_id, created_at) används för WHERE customer_id = ? ORDER BY created_at i en struktur.
N+1-problemet — en fråga för en lista, sedan en per rad — är en topporsak till långsamhet. Ersätt det med eager loading, en JOIN eller batchar 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;
Och välj bara behövda kolumner (undvik SELECT *) och paginera med LIMIT/keyset pagination så du aldrig laddar miljoner rader.
Databasen är den vanligaste flaskhalsen. Att läsa planen berättar varför en fråga är långsam istället för att gissa; rätt index, ta bort N+1 och trimma resultatmängden förvandlar rutinmässigt sekunder-långa frågor till millisekunder — utan att skala hårdvara.