Historia pytania:
Od samego początku zapytania SQL były projektowane jako deklaratywne: „co otrzymać”, a nie „jak otrzymać”. Optymalizator SGBD buduje plan wykonania (execution plan), który określa kolejność połączeń, filtrowania, skanowania i użycia indeksów.
Problem:
Bez zrozumienia planu wykonania nie można wyjaśnić, dlaczego zapytanie, które wydaje się proste, wykonuje się zbyt wolno, podczas gdy złożone działa szybko. Błędny plan może zablokować serwer na godziny z powodu zbędnych operacji lub niewłaściwego użycia indeksów.
Rozwiązanie:
Narzędzia analizy to instrukcje typu EXPLAIN, EXPLAIN ANALYZE (PostgreSQL), SHOW EXPLAIN (MySQL), Management Studio Execution Plan (SQL Server). Dzięki nim można zobaczyć krok po kroku, jak dokładnie wykonano zapytanie, jaki był wolumen danych przeczytanych, który z indeksów został użyty, gdzie miały miejsce skanowania całych tabel (table scan) i gdzie wystąpiły opóźnienia.
Przykład kodu:
EXPLAIN ANALYZE SELECT * FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = 'shipped';
Kluczowe cechy:
Czy dodanie indeksu zawsze przyspieszy zapytanie?
Nie! Indeks pomoże tylko wtedy, gdy filtrowanie według jego pola znacząco ogranicza liczbę zwracanych wierszy. Jeśli większość rekordów pasuje do warunku, optymalizator może zignorować indeks.
Przykład:
-- Pole 'gender' przyjmuje tylko dwa wartości — indeks nie pomoże CREATE INDEX idx_gender ON people(gender); SELECT * FROM people WHERE gender = 'M';
Czy kolejność tabel w JOIN wpływa na wynik wykonania?
Nie, dane końcowe będą takie same, jednak optymalizator może zmienić kolejność wykonywania połączeń dla zwiększenia wydajności. Ale jeśli napisano specyficzny JOIN lub użyto wskazówek typu "JOIN HINT", kolejność może wpłynąć na efektywność wykonania.
Po co analizować "Estimated rows" i "Actual rows" w planie wykonania?
Różnica między nimi może wskazywać, że statystyki dotyczące tabel są przestarzałe lub nieodzwierciedlające rzeczywistości, a wybrany plan nie jest optymalny — należy zaktualizować statystyki lub przemyśleć strukturę zapytania.
-- PostgreSQL ANALYZE table_name; -- zaktualizować statystyki
W projekcie analitycy długo skarżyli się na „zawieszanie” raportów. Zapytanie z pięcioma JOINami trwało 25 minut. Okazało się, że wybrano plan z pełnym skanowaniem ogromnej tabeli zamiast index scan, indeksy były nie na tych polach, a statystyka nie była aktualizowana od roku.
Zalety:
Wady:
Przeprowadzono analizę execution plan, dodano indeks na rzeczywiste pole filtrujące, zaktualizowano statystyki. Czas zapytania skrócił się do 20 sekund. Obciążenie serwera zmniejszyło się o rząd wielkości.
Zalety:
Wady: