Wydajność sklepu internetowego zależy w dużej mierze od stanu bazy danych. Gdy tabele rosną niekontrolowanie, a zapytania SQL wykonują się zbyt długo, czas ładowania stron rośnie, a konwersja spada. Poniżej znajdziesz praktyczne kroki, które pozwolą zdiagnozować problemy, naprawić strukturę indeksów i utrzymać porządek w logach bez ryzyka uszkodzenia danych.
Diagnoza problemów z wydajnością bazy danych
Pierwszym krokiem jest ustalenie, które zapytania obciążają serwer najbardziej. PrestaShop generuje setki zapytań przy każdym wejściu na stronę – od pobierania produktów po liczenie koszyka. Jeśli baza nie jest przygotowana do takiego ruchu, kolejka zapytań rośnie, a użytkownicy widzą biały ekran lub komunikat o przekroczeniu limitu czasu.
Identyfikacja wolnych zapytań
Włącz log wolnych zapytań w konfiguracji MySQL lub MariaDB (`slow_query_log = 1`, `long_query_time = 1`). Przeanalizuj plik logu narzędziem `mysqldumpslow` lub `pt-query-digest` z pakietu Percona Toolkit. Szukaj zapytań, które:
- pojawiają się często (wysoka liczba wywołań),
- trwają długo (wysoki czas całkowity),
- nie używają indeksów (kolumna `rows_examined` znacznie większa od `rows_sent`).
Typowe winowajce w PrestaShop to zapytania do `ps_product_shop` bez odpowiednich indeksów na `id_shop` i `active`, albo złączenia `ps_category_product` przy generowaniu menu megamenu.
Analiza planów zapytań (EXPLAIN)
Dla każdego podejrzanego zapytania uruchom `EXPLAIN`. Zwróć uwagę na kolumny:
- `type` – wartości `ALL` (pełne skanowanie tabeli) lub `index` (skanowanie całego indeksu) sygnalizują problem,
- `key` – `NULL` oznacza brak używanego indeksu,
- `rows` – szacowana liczba przetworzonych wierszy; jeśli jest rzędu tysięcy przy zwracaniu kilkudziesięciu rekordów, indeks jest nieadekwatny.
Zapisz wyniki `EXPLAIN` do pliku i porównuj po każdej zmianie struktury tabel.
Indeksy – budowa i utrzymanie
Indeksy to najtańszy sposób na przyspieszenie odczytu, ale każdy indeks spowalnia zapisy (INSERT, UPDATE, DELETE) i zajmuje miejsce na dysku. Celuj w minimalny zbiór indeksów pokrywających realne obciążenie produkcyjne.
Kiedy dodawać indeksy
Dodaj indeks, gdy:
- kolumna występuje w klauzuli `WHERE`, `JOIN` lub `ORDER BY` w zapytaniach z logu wolnych zapytań,
- kardinność kolumny (liczba unikalnych wartości) jest wysoka – indeks na `active` (0/1) rzadko pomaga, na `id_category` – zazwyczaj tak,
- zapytanie sortuje po kolumnie, która nie jest kluczem głównym.
Przykład: tabela `ps_product_lang` często filtrowana jest po `id_lang` i `id_shop`. Indeks złożony `(id_lang, id_shop, id_product)` pokryje większość zapytań listujących produkty w danym języku i sklepie.
Usuwanie nieużywanych indeksów
Sprawdź `sys.schema_unused_indexes` (MySQL 8.0+) lub tabelę `information_schema.INDEX_STATISTICS` (MariaDB/Percona). Indeks, który nie był czytany przez tydzień przy normalnym ruchu, można bezpiecznie usunąć. Pamiętaj, by najpierw zrobić zrzut struktury (`mysqldump –no-data`) – w razie błędu odtworzenie zajmie chwilę.
Czyszczenie logów i tabel tymczasowych
PrestaShop gromadzi ogromne ilości danych historycznych, których nie potrzebujesz do codziennej sprzedaży. Tabele logów rosną do gigabajtów, zwiększając czas backupu i rozmiar plików `ibdata1`.
Tabele ps_log, ps_connections, ps_guest
- `ps_log` – zapisuje błędy i zdarzenia. Ustaw cron, który co noc usuwa wpisy starsze niż 30 dni:
`DELETE FROM ps_log WHERE date_add < DATE_SUB(NOW(), INTERVAL 30 DAY) LIMIT 10000;` (Limit 10 000 zapobiega blokadzie tabeli na dłużej niż sekundę).
- `ps_connections` i `ps_guest` – przechowują sesje gości. Jeśli nie analizujesz ścieżek klientów w czasie rzeczywistym, wyczyść wpisy starsze niż 7 dni.
- `ps_search_index` – po reindeksowaniu wyszukiwania stare wpisy pozostają w bazie. Uruchom `TRUNCATE ps_search_index` przed pełnym reindeksem z back-office.
Automatyzacja czyszczenia
Stwórz skrypt bashowy lub zadanie w `cron.d`, który:
- Sprawdza rozmiar tabel (`information_schema.TABLES`),
- Uruchamia `DELETE` w partiach po 5 000-10 000 wierszy z pauzą `SLEEP(0.5)` między partiami,
- Loguje czas trwania i liczbę usuniętych rekordów do pliku `/var/log/prestashop_cleanup.log`.
Unikaj `TRUNCATE` na tabelach z kluczami obcymi (np. `ps_cart` powiązane z `ps_orders`) – naruszyłoby to integralność referencyjną.
Konfiguracja serwera bazy danych
Dobra struktura tabel nie zastąpi złej konfiguracji silnika. Poniżej parametry, które najczęściej wymagają dostrojenia w środowisku PrestaShop.
Bufor zapytań i sortowania
- `query_cache_type = 0` – bufor zapytań w MySQL 5.7 i starszych powoduje kontencję na mutexie przy dużym ruchu zapisywać. Wyłącz go.
- `sort_buffer_size = 4M` – zwiększ, jeśli widzisz `Sort_merge_passes` rosnące w `SHOW GLOBAL STATUS`. Nie przesadzaj – bufor alokowany na połączenie.
- `tmp_table_size` i `max_heap_table_size` – ustaw na 64M-128M, by tabel tymczasowe mieszcząły się w RAM, a nie na dysku.
InnoDB buffer pool
To najważniejszy parametr wydajnościowy. Ustaw `innodb_buffer_pool_size` na 70-80 % dostępnej pamięci RAM (np. 24 GB przy 32 GB RAM). Włącz `innodb_buffer_pool_instances = 8` (dla puli > 1 GB), by zmniejszyć kontencję. Monitoruj `Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests` – stosunek powinien być poniżej 1 %.
Narzędzia wspomagające optymalizację
Ręczna analiza logów i planów zapytań jest czasochłonna. Warto wdrożyć narzędzia ciągłego monitoringu:
- Percona Monitoring and Management (PMM) – darmowa platforma z dashboardami dla MySQL/MariaDB, MongoDB, PostgreSQL. Pokazuje top queries, blokady, I/O, replikację.
- MySQLTuner / Tuning Primer – skrypty perlowe dające szybkie rekomendacje po uruchomieniu. Traktuj je jako punkt wyjścia, nie ostateczną prawdę.
- pt-online-schema-change – pozwala dodawać/usuwać indeksy i zmieniać typy kolumn bez blokady tabeli na czas migracji. Kluczowe na żywym sklepie.
- pt-archiver – do masowego usuwania starych danych w partiach z kontrolą obciążenia replikacji.
Regularne przeglądy raportów z PMM (raz w tygodniu) pozwalają złapać regresje wydajnościowe po aktualizacji modułów lub wersji PrestaShop.
Kiedy warto zlecić audyt profesjonalny
Samodzielna optymalizacja bazy danych daje duże zyski, ale istnieją sytuacje, gdy bezpieczniej i taniej jest poprosić o pomoc zewnętrzną:
- Baza przekracza 20 GB, a backup trwa godzinami – potrzebna strategia partycjonowania lub archiwizacji.
- Występują deadlocki, których nie da się wyeliminować indeksami (np. konflikty w `ps_stock_available` przy importach).
- Planujesz migrację na nowszy silnik (MySQL 8.0 → MariaDB 10.6, Percona Server) i chcesz uniknąć przestojów.
- Zespół nie ma doświadczenia w dostrojeniu `innodb_io_capacity`, `innodb_flush_neighbors` czy `innodb_adaptive_hash_index`.
W takich przypadkach warto rozważyć audyt prestashop przeprowadzony przez specjalistów, którzy przeanalizują obciążenie produkcyjne, zaproponują zmiany schematu i wdrożą je bez ryzyka utraty danych. Jeśli wolisz najpierw poznać zakres problemów, możesz zamówić pre-audyt optymalizacji i przyspieszenia sklepu, który wskazuje priorytety bez ingerencji w bazę.
Dla sklepów, które chcą kompleksowo podnieść wydajność – nie tylko bazy, ale też frontendu, cache’u i serwera aplikacji – dostępna jest optymalizacja prestashop obejmująca wszystkie warstwy stosu technologicznego. Jeśli zależy Ci na szybkim efekcie przy minimalnym ryzyku, sprawdź ofertę optymalizacji szybkości prestashop – gotowe pakiety wdrożeniowe z gwarancją poprawy Core Web Vitals.
FAQ
Jak często czyszczyć tabele logów w PrestaShop? Zalecane cykliczne czyszczenie co noc dla `ps_log` (retencja 30 dni) i co tydzień dla `ps_connections` / `ps_guest` (retencja 7 dni). Automatyzuj to cronem z partiami po 5-10 tys. wierszy.
Czy mogę usunąć indeks PRIMARY KEY, by zaoszczędzić miejsce? Nie. Klucz główny jest fundamentem klastrowania danych w InnoDB. Jego usunięcie zniszczy strukturę tabeli i uniemożliwi szybkie wyszukiwanie po ID.
Dlaczego po dodaniu indeksu zapytanie wciąż jest wolne? Sprawdź `EXPLAIN` – optymalizator może ignorować indeks przy niskiej selektywności (np. kolumna `active` z 90 % wartości 1). Wymuszenie indeksu (`FORCE INDEX`) pomaga testowo, ale lepszym rozwiązaniem jest indeks złożony pokrywający więcej kolumn z klauzuli `WHERE`.
Czy włączenie query_cache poprawi wydajność sklepu? W nowoczesnych wersjach MySQL (5.7+) i MariaDB bufor zapytań domyślnie wyłączony i zaleca się tak zostawić. Na dużym ruchu zapisywać powoduje kontencję globalnego mutexu, co spowalnia całą bazę.
Masz pytania związane z tym tematem? Skontaktuj się ze mną:
Chętnie Ci pomogę w tym zakresie
Email: [email protected]
Telefon: +48 888 830 888
Strona: https://helpguru.eu