 Autor: [Miłka Teroy](/autorzy/milka-teroy) Analityk rynku hostingowego · Zweryfikowano Kwiecień 2026

1.  [Strona główna](/) ›
2.  [Baza wiedzy](/baza-wiedzy/) ›
3.  MySQL slow query log — optymalizacja

# MySQL slow query log — znajdowanie i optymalizacja wolnych zapytań SQL

Opublikowano: 9 kwietnia 2026 · Kategoria: Bazy danych

WordPress ładuje się 5 sekund, a MySQL zjada 80% CPU serwera? Najprawdopodobniej winne są wolne zapytania SQL bez indeksów — pełne table scany na setkach tysięcy wierszy. MySQL slow query log to wbudowane narzędzie diagnostyczne, które rejestruje dokładnie te zapytania. Dowiedz się jak je znaleźć i naprawić.

## Włączenie slow query log

Dodaj do `/etc/mysql/mysql.conf.d/mysqld.cnf` (Ubuntu) lub `/etc/my.cnf` (CentOS):

\[mysqld\]
# Włącz slow query log
slow\_query\_log = 1
slow\_query\_log\_file = /var/log/mysql/mysql-slow.log

# Próg w sekundach (1s to dobry punkt startowy)
long\_query\_time = 1

# Loguj też zapytania bez indeksów (przydatne dla diagnostyki)
log\_queries\_not\_using\_indexes = 1

# Ogranicz logi "no index" do 200/min (żeby nie zapchać logu)
log\_throttle\_queries\_not\_using\_indexes = 200

\# Restart MySQL
sudo systemctl restart mysql

# Lub włącz dynamicznie (bez restartu) — efekt do następnego restartu
mysql -u root -p -e "SET GLOBAL slow\_query\_log = ON;"
mysql -u root -p -e "SET GLOBAL long\_query\_time = 1;"
mysql -u root -p -e "SET GLOBAL log\_queries\_not\_using\_indexes = ON;"

# Sprawdź aktualne ustawienia
mysql -u root -p -e "SHOW VARIABLES LIKE 'slow%';"
mysql -u root -p -e "SHOW VARIABLES LIKE 'long\_query\_time';"

## Analiza — mysqldumpslow

`mysqldumpslow` jest dołączony do MySQL. Agreguje podobne zapytania i sortuje wyniki:

\# 10 najwolniejszych zapytań (sort by query time)
mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log

# 10 najczęstszych wolnych zapytań
mysqldumpslow -s c -t 10 /var/log/mysql/mysql-slow.log

# Zapytania zawierające "wp\_posts"
mysqldumpslow -g "wp\_posts" /var/log/mysql/mysql-slow.log

# Przykładowy output:
# Count: 423  Time=2.15s (910s)  Lock=0.00s (0s)  Rows=1000.0 (423000)
# SELECT \* FROM wp\_posts WHERE post\_status='S' AND post\_type='S'

## Analiza — pt-query-digest (Percona Toolkit)

Percona Toolkit to potężniejsze narzędzie — grupuje zapytania, pokazuje percentyle i procentowy udział w łącznym czasie:

\# Instalacja
sudo apt install percona-toolkit  # Ubuntu/Debian

# Analiza slow logu
pt-query-digest /var/log/mysql/mysql-slow.log | head -100

# Output zawiera:
# Rank  Response time  Calls  R/Call  V/M  Item
# 1     245.3123 42.0%   1823  0.1346  0.16 SELECT wp\_posts wp\_postmeta
# ...
# Detailed view: pełne zapytanie + statystyki czasu

## EXPLAIN — diagnostyka planu wykonania

Po znalezieniu problematycznego zapytania, użyj `EXPLAIN` żeby zrozumieć dlaczego jest wolne:

EXPLAIN SELECT \* FROM wp\_posts
WHERE post\_status = 'publish'
AND post\_type = 'post'
ORDER BY post\_date DESC
LIMIT 10;

-- Wynik: tabela z kolumnami:
-- id | select\_type | table | type | possible\_keys | key | rows | Extra
--  1 | SIMPLE | wp\_posts | ALL  | NULL  | NULL | 84523 | Using where; Using filesort

type

Znaczenie

Ocena

`system / const`

Zapytanie o 1 wiersz przez PK lub UNIQUE

Doskonałe

`eq_ref`

JOIN przez unikalny indeks, 1 wiersz na match

Bardzo dobry

`ref`

Użycie indeksu (nieunikalnego)

Dobry

`range`

Skanowanie zakresu przez indeks (BETWEEN, )

Akceptowalny

`index`

Pełny skan indeksu (lepsza niż ALL)

Słaby

`ALL`

Pełny table scan — każdy wiersz sprawdzany

Krytyczny

## Dodawanie indeksów

\-- Problem: brak indeksu na (post\_status, post\_type)
-- Rozwiązanie: composite index
ALTER TABLE wp\_posts
ADD INDEX idx\_status\_type\_date (post\_status, post\_type, post\_date);

-- Sprawdź istniejące indeksy
SHOW INDEX FROM wp\_posts;

-- Weryfikacja po dodaniu indeksu (EXPLAIN powinien teraz pokazać ref)
EXPLAIN SELECT \* FROM wp\_posts
WHERE post\_status = 'publish' AND post\_type = 'post'
ORDER BY post\_date DESC LIMIT 10;

**Uwaga:** Na współdzielonym hostingu (cPanel/DirectAdmin) zazwyczaj masz uprawnienia do tworzenia indeksów przez phpMyAdmin. Na VPS możesz robić to bezpośrednio w MySQL CLI.

## Optymalizacja WordPress — typowe problemy

-   **wp\_options autoload** — zapytanie `SELECT * FROM wp_options WHERE autoload='yes'` ładuje wszystkie opcje przy każdym żądaniu. Sprawdź: `SELECT COUNT(*), SUM(LENGTH(option_value)) FROM wp_options WHERE autoload='yes'`. Jeśli powyżej 1 MB — wyczyść nieużywane opcje wtyczek.
-   **wp\_postmeta bez indeksu** — zapytania przez `meta_key` często nie używają indeksu. Wtyczka Query Monitor (WordPress) pokaże wolne zapytania w panelu admina.
-   **Brak limitu w WP\_Query** — `posts_per_page=-1` ładuje WSZYSTKIE posty. Zawsze ustawiaj limit.
-   **JOIN na dużych tabelach** — tabele wp\_posts + wp\_postmeta mogą mieć miliony wierszy. Użyj WP Object Cache (Redis/Memcached) żeby cache'ować wyniki.

## Najczęstsze pytania

Co to jest slow query log MySQL i kiedy go włączyć? +

Slow query log MySQL rejestruje zapytania SQL trwające dłużej niż ustawiony próg (long\_query\_time, domyślnie 10 sekund). Włącz go gdy: strona ładuje się wolno, MySQL zużywa dużo CPU, albo widzisz błąd "waiting for table-level lock". Analiza slow log to pierwszy krok diagnostyki wydajności bazy danych.

Jak włączyć slow query log w MySQL/MariaDB? +

W /etc/mysql/mysql.conf.d/mysqld.cnf dodaj: slow\_query\_log = 1, slow\_query\_log\_file = /var/log/mysql/mysql-slow.log, long\_query\_time = 1. Potem sudo systemctl restart mysql. Lub włącz dynamicznie (bez restartu): SET GLOBAL slow\_query\_log = ON; SET GLOBAL long\_query\_time = 1;

Jak analizować slow query log? +

Użyj narzędzia mysqldumpslow: mysqldumpslow -t 10 /var/log/mysql/mysql-slow.log pokaże 10 najwolniejszych zapytań. Lepsza opcja: pt-query-digest z Percona Toolkit — grupuje podobne zapytania i pokazuje statystyki (ile razy, średni czas, procent całkowitego czasu). Następnie użyj EXPLAIN SELECT... na podejrzanych zapytaniach.

Jak EXPLAIN pomaga zoptymalizować zapytanie? +

EXPLAIN SELECT \* FROM users WHERE email = "jan@example.com" pokazuje plan wykonania zapytania. Szukaj: type=ALL (pełny table scan — zły), rows=duża\_liczba, Extra=Using filesort/Using temporary. Jeśli type=ALL na dużej tabeli — dodaj INDEX na kolumnie WHERE. type=ref lub eq\_ref to dobry znak — zapytanie używa indeksu.

## Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.

Contabo

VPS z rootem — pełna kontrola nad MySQL i slow query logiem

Root MySQL access

[Aktywuj rabat →](/out/contabo)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/contabo)

LH.pl

Hosting z phpMyAdmin i dostępem do baz MySQL

MySQL hosting

[Aktywuj rabat →](/out/lh-pl)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/lh-pl)

Zenbox

SSD hosting z szybkim MySQL i SLA 99,9%

SSD + MySQL

[Aktywuj rabat →](/out/zenbox)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/zenbox)

## Powiązane strony

-   [MySQL na hostingu — konfiguracja i optymalizacja](/baza-wiedzy/mysql-baza-danych-hosting)
-   [MariaDB vs MySQL — różnice i migracja](/baza-wiedzy/mariadb-vs-mysql-hosting)
-   [Redis cache dla WordPress](/baza-wiedzy/redis-cache-wordpress)
-   [WordPress cache — optymalizacja wydajności](/baza-wiedzy/wordpress-cache-optymalizacja)
-   [Wszystkie artykuły](/baza-wiedzy/)