Slow Query Log — sekin so'rovlarni topish

~15 daq · MySQL · Index va Performance

Muammodan boshlaylik

Foydalanuvchilar shikoyat qiladi: "Sayt ba'zan sekin ishlaydi". Qaysi sahifa? Qaysi so'rov? Ilovada yuzlab turli SQL so'rov bor. EXPLAIN ni hammasiga birma-bir qo'llash — bir hafta ish.

Avval qaysi so'rovlar sekin ekanini aniqlash kerak. MySQL buni o'zi yozib boradi — slow query log ga.


Yoqish

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;          -- 1 soniyadan uzoq so'rovlar
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';

Server qayta ishga tushganda ham saqlanishi uchun — konfiguratsiya faylida (my.cnf / my.ini):

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
Sozlama Ma'nosi
long_query_time Shu soniyadan uzoq so'rovlar yoziladi (kasr ham mumkin: 0.5)
log_queries_not_using_indexes Indekssiz so'rovlar — tez bo'lsa ham (kichik jadvallar ham tushadi — shovqinli)
min_examined_row_limit Kamida shuncha qator o'qigan so'rovlar

[!TIP] Boshida long_query_time = 1 bilan boshlang. Asosiy muammolar tuzatilgach — 0.5, keyin 0.1 ga tushiring. 0 — barcha so'rovlar yoziladi: tahlil uchun qisqa muddatga foydali, lekin disk tez to'ladi.


Log fayl ichida nima bor

# Time: 2026-11-04T10:15:32.123456Z
# User@Host: dokon_app[dokon_app] @ localhost []  Id:   847
# Query_time: 3.482115  Lock_time: 0.000102  Rows_sent: 20  Rows_examined: 4800000
SET timestamp=1793787332;
SELECT id, yaratilgan FROM buyurtmalar WHERE holat = 'yangi' ORDER BY yaratilgan DESC LIMIT 20;
Maydon Ma'nosi
Query_time So'rov qancha davom etdi
Lock_time Qulfni kutish vaqti
Rows_sent Mijozga qaytarilgan qatorlar
Rows_examined O'qilgan qatorlar

Eng muhim signal — Rows_examined va Rows_sent nisbati. 20 ta qator uchun 4.8 million o'qilgan — indeks yo'q yoki noto'g'ri.


mysqldumpslow — umumlashtirish

Log faylda minglab yozuv bo'ladi. Bir xil so'rov turli qiymatlar bilan yuzlab marta takrorlanadi. mysqldumpslow ularni guruhlaydi:

mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
  • -s t — umumiy vaqt bo'yicha saralash (c — soni, at — o'rtacha vaqt)
  • -t 10 — top 10
Count: 1840  Time=2.91s (5354s)  Lock=0.00s (0s)  Rows=20.0 (36800)
  SELECT id, yaratilgan FROM buyurtmalar WHERE holat = 'S' ORDER BY yaratilgan DESC LIMIT N

Count: 12  Time=8.40s (100s)  Lock=0.00s (0s)  Rows=1.0 (12)
  SELECT COUNT(*) FROM mijozlar m JOIN ... 

Qiymatlar 'S' (string) va N (son) bilan almashtirilgan — bir xil shakldagi so'rovlar bitta guruhga.

Muhim: birinchi so'rov bittasi 2.9 soniya, lekin 1840 marta — jami 89 daqiqa. Ikkinchisi 8.4 soniya, lekin atigi 12 marta. Birinchisini tuzatish ancha foydali. Umumiy vaqt bo'yicha saralang, bitta so'rov vaqti bo'yicha emas.

Kuchliroq vosita — pt-query-digest (Percona Toolkit): batafsil statistika, foizlar, taqsimot.


Performance Schema — log siz

MySQL 8 da log faylsiz ham statistika to'planadi:

SELECT
    DIGEST_TEXT                              AS sorov,
    COUNT_STAR                               AS soni,
    ROUND(SUM_TIMER_WAIT / 1e12, 2)          AS jami_soniya,
    ROUND(AVG_TIMER_WAIT / 1e12, 3)          AS ortacha_soniya,
    SUM_ROWS_EXAMINED                        AS oqilgan_qatorlar,
    SUM_NO_INDEX_USED                        AS indekssiz
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;

Yoki tayyor ko'rinish (sys sxemasi):

SELECT * FROM sys.statements_with_full_table_scans LIMIT 10;
SELECT * FROM sys.statement_analysis LIMIT 10;

Ishlatilmayotgan indekslar (o'chirish uchun nomzodlar):

SELECT * FROM sys.schema_unused_indexes WHERE object_schema = 'dokon';

[!INFO] Bu statistika server qayta ishga tushirilgandan beri to'planadi. Yangi ishga tushirilgan serverda "ishlatilmagan" indeks haqiqatan ham keraksiz bo'lmasligi mumkin — oylik hisobot uchun ishlatiladigan indeks bir oy jim turadi.


Hozir nima bajarilyapti?

Sayt "osilib" qoldi — aynan hozir nima bo'lyapti?

SHOW FULL PROCESSLIST;
+-----+-----------+-----------+-------+---------+------+--------------+---------------------------+
| Id  | User      | Host      | db    | Command | Time | State        | Info                      |
+-----+-----------+-----------+-------+---------+------+--------------+---------------------------+
| 847 | dokon_app | localhost | dokon | Query   |  142 | Sending data | SELECT ... FROM buyurtma..|
| 851 | dokon_app | localhost | dokon | Query   |  138 | Waiting for  | UPDATE mahsulotlar ...    |
|     |           |           |       |         |      | table lock   |                           |
+-----+-----------+-----------+-------+---------+------+--------------+---------------------------+

Time — necha soniyadan beri bajarilyapti. 142 soniyalik so'rov boshqa so'rovlarni bloklab turgan bo'lishi mumkin.

To'xtatish:

KILL QUERY 847;    -- faqat so'rovni
KILL 847;          -- butun ulanishni

Ilova darajasida

Baza logidan tashqari, ilovada ham so'rovlarni kuzatish foydali:

  • Laravel — Telescope, Debugbar: har bir sahifada qanday so'rovlar va qancha vaqt
  • Node.js — ORM loglari (logging: true)
  • APM vositalari — New Relic, Datadog, Sentry Performance

Ular "qaysi sahifa sekin va unda nechta so'rov" ni ko'rsatadi — N+1 muammosini (18-dars) aynan shu yerda ko'rasiz: bitta sahifada 300 ta bir xil so'rov.


Nima uchun shunday?

Nima uchun sekin so'rovlarni oldindan, kod yozayotganda topib bo'lmaydi?

Chunki tezlik ma'lumotga bog'liq. Dasturchi kompyuterida 100 ta buyurtma — har qanday so'rov bir zumda. Production da 5 million — va ba'zi so'rovlar birdan minglab marta sekinlashadi. Bundan tashqari, real foydalanuvchilar siz kutmagan filtrlar va kombinatsiyalarni ishlatadi. Shuning uchun optimizatsiya — kuzatish bilan boshlanadi: avval o'lchang, keyin tuzating. Slow query log — o'lchash vositasi.


Xulosa

Eslab qoling:

  • slow_query_log = ON, long_query_time = 1 — sekin so'rovlarni yozish
  • Logda: Query_time, Rows_examined vs Rows_sent — asosiy signal
  • mysqldumpslow -s t — umumiy vaqt bo'yicha top so'rovlar
  • Tez-tez bajariladigan "o'rtacha sekin" so'rov — ko'pincha eng katta muammo
  • performance_schema / sys — logsiz statistika, ishlatilmagan indekslar
  • SHOW FULL PROCESSLIST + KILL QUERY — hozirgi muammolar
  • Avval o'lchang, keyin optimizatsiya qiling

Keyingi dars

34-dars: Query optimizatsiya — N+1, covering index, qoidalar