Gdy WordPress ładuje się wolno mimo dobrego wyniku PageSpeed, problem może powstawać jeszcze przed renderowaniem strony. Wysoki TTFB często oznacza, że PHP i baza danych długo przygotowują odpowiedź, a winowajcą bywa pojedyncze kosztowne zapytanie SQL albo wiele drobnych zapytań wykonywanych w pętli.
Dlaczego PageSpeed nie pokazuje całego problemu?
PageSpeed i Lighthouse koncentrują się głównie na tym, jak przeglądarka pobiera i renderuje stronę. Nie pokazują dokładnie, które zapytanie do bazy opóźniło wygenerowanie HTML. Dlatego witryna może uzyskać dobry wynik, a użytkownik nadal czekać kilka sekund na rozpoczęcie odpowiedzi serwera.
W takiej sytuacji sprawdź TTFB, czyli czas od wysłania żądania do otrzymania pierwszego bajtu. Wysoki wynik wskazuje na problem po stronie backendu, na przykład wolne zapytania SQL, przeciążone PHP, zewnętrzne API albo brak cache obiektowego. Page cache może ukryć problem dla części odwiedzających, ale nie usuwa go z żądań administracyjnych, koszyka, checkoutu i cache missów.
Jak znaleźć wolne zapytania w WordPress?
Najpierw trzeba zebrać dane z konkretnego żądania lub z rzeczywistego ruchu. Trzy metody odpowiadają na nieco inne potrzeby:
| Metoda | Dla kogo | Bezpieczeństwo na produkcji | Zaleta |
|---|---|---|---|
| Query Monitor | Deweloper i administrator | Najlepiej używać na stagingu lub podczas krótkiej diagnostyki | Pokazuje czas zapytań oraz kod, który je wywołał |
SAVEQUERIES |
Osoba potrzebująca szybkiego podglądu przez $wpdb |
Nie zostawiać włączonego na stałe | Udostępnia zapytania i ich czas wykonania w WordPressie |
| MySQL Slow Query Log | Administrator serwera i zaawansowany deweloper | Może działać na produkcji po ustawieniu rozsądnego progu | Rejestruje wolne zapytania także podczas ruchu, którego nie obserwujesz ręcznie |
Query Monitor i SAVEQUERIES
Query Monitor pozwala sprawdzić zapytania wykonane podczas ładowania konkretnej strony. W panelu zobaczysz między innymi czas pojedynczych zapytań, łączny czas pracy bazy oraz funkcję lub wtyczkę, która uruchomiła daną operację.
W przypadku krótkiego testu możesz włączyć w wp-config.php:
define( 'SAVEQUERIES', true );
Następnie dane są dostępne w tablicy $wpdb->queries. To dobre rozwiązanie do środowiska deweloperskiego, ale nie do stałego monitoringu działającej witryny.
Log wolnych zapytań MySQL
Jeśli masz dostęp do konfiguracji serwera, log wolnych zapytań może rejestrować operacje przekraczające ustalony czas, także podczas rzeczywistego ruchu. Próg powinien wynikać z potrzeb witryny. Zbyt niski może wygenerować bardzo dużo danych, a zbyt wysoki pominie zapytania, które wykonywane są często i łącznie mocno obciążają serwer.
Jak analizować znalezione zapytanie za pomocą EXPLAIN?
Samo znalezienie długiego SQL-a to dopiero początek. Trzeba sprawdzić, jak MySQL planuje go wykonać. Przed zapytaniem typu SELECT dodaj EXPLAIN, a następnie przeanalizuj wynik. Najważniejsze są trzy pola:
type– pokazuje sposób dostępu do danych. Warto zwrócić uwagę naALL, które oznacza pełny skan tabeli.key– informuje, czy MySQL użył indeksu. WartośćNULLoznacza, że dla danego kroku indeks nie został wykorzystany.rows– szacuje liczbę wierszy do sprawdzenia. Duża wartość przytype: ALLjest wyraźnym sygnałem problemu.
Typowym przykładem jest filtrowanie produktów WooCommerce w tabeli wp_postmeta. Zapytanie może łączyć kilka rekordów dla tego samego produktu, na przykład cenę i stan magazynowy. Jeżeli plan pokazuje type: ALL, key: NULL i setki tysięcy wierszy, baza przegląda całą tabelę, zamiast szybko zawęzić wynik.
W takim przypadku nie zakładaj od razu indeksu na każdej kolumnie. Sprawdź, czy problem wynika z warunków w WHERE lub JOIN, jaka jest selektywność danych i czy indeks złożony pasuje do rzeczywistego zapytania. Po zmianie uruchom EXPLAIN ponownie i porównaj plan, liczbę analizowanych wierszy oraz czas wykonania.
Nie zostawiaj
SAVEQUERIESna stałe na produkcji. WordPress przechowuje informacje o każdym zapytaniu w pamięci, więc przy większym ruchu narzut może być bardzo duży.
Najczęstsze przyczyny wolnych zapytań WordPress
W praktyce problemy najczęściej wynikają z jednego z poniższych wzorców:
- Wiele JOIN-ów na
wp_postmeta– WooCommerce przechowuje wiele danych produktów w modelu klucz–wartość, co komplikuje filtrowanie po cenie, atrybutach i stanie. - Zapytania
LIKE '%term%'– wyszukiwanie z symbolem wieloznacznym na początku zwykle nie korzysta ze standardowego indeksu i może skanować całą kolumnę. - Problem N+1 – kod pobiera listę wpisów, a następnie wykonuje osobne zapytanie dla każdego elementu zamiast użyć pobierania wsadowego.
- Nieograniczone
WP_Query– parametrposts_per_page => -1może działać na małej stronie, ale przy tysiącach rekordów zwraca zbyt dużo danych naraz.
Przy zapytaniach WooCommerce sprawdź też, czy gorące dane katalogowe nie powinny korzystać z dedykowanej tabeli lookup zamiast z wielu odczytów z wp_postmeta. W przypadku powtarzalnych, rzadko zmienianych wyników pomocny może być trwały object cache, na przykład Redis. Nie zastąpi on złego planu wykonania, ale ograniczy powtarzanie tych samych odczytów.
Co zrobić po znalezieniu winowajcy?
Pracuj w stałej kolejności, aby nie mieszać efektów kilku zmian:
- Zmierz TTFB, liczbę zapytań oraz czas ich wykonania dla konkretnej strony.
- Włącz diagnostykę na stagingu przez Query Monitor albo tymczasowo przez
SAVEQUERIES. - Wybierz zapytania o największym czasie łącznym, nie tylko te, które pojedynczo trwają najdłużej.
- Uruchom
EXPLAINi sprawdźtype,keyorazrows. - Wprowadź jedną zmianę, na przykład właściwy indeks, ograniczenie wyników, pobieranie wsadowe albo cache wyniku.
- Powtórz pomiar w porównywalnych warunkach i cofnij zmianę, jeśli plan lub czas się nie poprawił.
Przed zmianami strukturalnymi wykonaj kopię zapasową bazy i przetestuj rozwiązanie poza produkcją. Dotyczy to zwłaszcza indeksów na dużych tabelach, zmian zapytań WooCommerce oraz modyfikacji kodu odpowiedzialnego za koszyk i checkout.
Zmierz, zdiagnozuj, napraw, sprawdź ponownie
Najlepsza metoda szukania wolnych zapytań w WordPressie nie polega na instalowaniu kolejnych narzędzi ani dodawaniu indeksów w ciemno. Zacznij od TTFB i pomiaru, znajdź zapytanie, odczytaj jego plan przez EXPLAIN, wprowadź jedną poprawkę i porównaj wynik. Dzięki temu optymalizujesz rzeczywiste wąskie gardło, a nie tylko objawy.