TL;DR
Indeksy przyspieszają wyszukiwanie i sortowanie w bazie. Źle dobrane lub brak indeksów prowadzą do wolnych zapytań i full table scan. Oto kiedy dodawać indeksy i jak optymalizować zapytania w 2026.
Dla kogo to jest
- Deweloperów piszących zapytania SQL i ORM (Prisma, TypeORM)
- Zespołów dbających o wydajność backendu
- Osób analizujących wolne zapytania w produkcji
Fraza (SEO)
indeksy bazy danych, optymalizacja zapytań, postgresql, mysql, wydajność, explain
Po co indeksy?
- Szybsze wyszukiwanie –
WHERE id = ?,WHERE email = ?zamiast skanowania całej tabeli - Szybsze sortowanie –
ORDER BY created_atz indeksem nacreated_at - Szybsze JOINy – indeks na kolumnie łączącej (klucz obcy)
- Unikanie full table scan – na dużych tabelach full scan = wolne zapytania
Kiedy dodawać indeks?
- Kolumny w WHERE (np.
user_id,status,email) - Kolumny w ORDER BY (np.
created_at DESC) - Kolumny w JOIN (klucze obce)
- Kolumny w UNIQUE / PRIMARY KEY (zazwyczaj indeks automatyczny)
Kiedy unikać nadmiaru indeksów?
- Każdy indeks spowalnia INSERT/UPDATE/DELETE (baza musi aktualizować indeks)
- Małe tabele – często full scan jest wystarczająco szybki
- Kolumny rzadko używane w WHERE – indeks może nie być wart zachodu
ANALYZE / EXPLAIN – jak szukać wolnych zapytań
PostgreSQL:
EXPLAIN ANALYZE
SELECT * FROM orders WHERE user_id = 123 ORDER BY created_at DESC LIMIT 10;
Szukaj w wyniku:
- Seq Scan (full table scan) na dużej tabeli – często sygnał do indeksu
- Index Scan / Index Only Scan – użycie indeksu, zwykle OK
- cost – wyższy cost = droższe zapytanie
Prisma: włącz log: ['query'] w dev i mierz czas zapytań; wolne zapytania analizuj w bazie przez EXPLAIN.
Przykład: indeks na często filtrowaną kolumnę
-- Tabela orders, często: WHERE user_id = ? ORDER BY created_at DESC
CREATE INDEX idx_orders_user_created ON orders (user_id, created_at DESC);
Złożony indeks (user_id, created_at) może obsłużyć zarówno filtr po user_id, jak i sortowanie po created_at bez osobnego sortowania.
Checklist / kroki
- Włącz logowanie wolnych zapytań (np. PostgreSQL
log_min_duration_statement) - Dla wolnych zapytań uruchom EXPLAIN ANALYZE
- Dodaj indeksy na kolumny w WHERE i ORDER BY używane w tych zapytaniach
- Unikaj indeksów na każdej kolumnie – ważna jest równowaga
- Po dodaniu indeksu zmierz czas zapytania ponownie
FAQ
Czy indeks na każdej kolumnie to dobry pomysł?
Nie. Zbyt wiele indeksów spowalnia zapisy i zajmuje miejsce. Dodawaj indeksy pod konkretne zapytania (WHERE, ORDER BY, JOIN).
Co to jest composite index?
Indeks złożony z kilku kolumn, np. (user_id, created_at). Kolejność kolumn ma znaczenie – pierwsza kolumna powinna być tą, po której najczęściej filtrujesz.
Gdy zapytanie dalej jest wolne po dodaniu indeksu?
Sprawdź, czy plan wykonania (EXPLAIN) rzeczywiście używa indeksu. Czasem baza wybiera full scan (np. gdy zwracana jest duża część wierszy). Zawęź wynik (LIMIT, lepsze WHERE) lub rozważ partycjonowanie tabeli.