وقتی سایت کند میشه، اغلب مشکل MySQL هست. Slow Query Log ابزار قدرتمندی برای پیدا کردن کوئریهای مشکلداره. تو این مقاله کامل استفاده رو یاد میگیرید.
Slow Query Log چیه؟
ویژگی MySQL که هر کوئری بیشتر از یه زمان مشخص طول میکشه رو ثبت میکنه. با تحلیلش، مشکلات performance رو پیدا میکنید.
فعالسازی
در my.cnf
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
Runtime
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
پارامترها
long_query_time
حداقل زمان کوئری برای log. مثلاً 1 = یک ثانیه.
log_queries_not_using_indexes
کوئریهای بدون Index رو هم log کنید، حتی اگه سریع باشن.
min_examined_row_limit
حداقل تعداد سطر بررسی شده.
ساختار Log
هر کوئری در Log:
# Time: 2026-07-23T10:30:15
# User@Host: root[root] @ localhost []
# Query_time: 2.5 Lock_time: 0.1
# Rows_sent: 100 Rows_examined: 100000
SELECT * FROM orders WHERE customer_id = 42;
ابزار تحلیل
mysqldumpslow
ابزار پیشفرض:
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
ده کوئری کند رو نشون میده.
pt-query-digest
حرفهایترین:
pt-query-digest slow.log > report.txt
گزارش کامل، خلاصه.
Percona QAN
GUI برای تحلیل.
مثال تحلیل
پرترافیکترین
کوئریهای که زیاد اجرا میشن. Cache کنید.
کندترین
کوئریهایی که بیشترین زمان میگیرن.
بیشترین ردیف
کوئریهایی که هزاران ردیف بررسی میکنن.
EXPLAIN
بعد پیدا کردن کوئری کند:
EXPLAIN SELECT * FROM orders WHERE customer_id = 42;
ستونها:
- type: ALL = بد، ref = خوب، const = عالی
- possible_keys: Indexهای موجود
- key: Index استفاده شده
- rows: تخمین سطر بررسی
راهحلهای رایج
Index
ALTER TABLE orders ADD INDEX idx_customer_id (customer_id);
Composite Index
برای WHERE با چند شرط:
CREATE INDEX idx_customer_status ON orders(customer_id, status);
Cover Index
Index شامل همه ستونهای SELECT.
Limit
SELECT ... LIMIT 100;
Not SELECT *
فقط ستونهای لازم:
SELECT id, name FROM users;
Cache Layer
Redis یا Memcached برای کوئریهای تکراری.
N+1 Problem
مثال Bad:
// در حلقه
SELECT * FROM users;
foreach ($users as $user) {
SELECT * FROM orders WHERE user_id = $user->id;
}
راهحل: JOIN یا Eager Loading.
Full Table Scan
type = ALL در EXPLAIN. یعنی همه جدول رو میخونه.
راه: Index مناسب.
File Sort
Extra = Using filesort. برای ORDER BY بدون Index.
راه: Index روی ORDER BY column.
Temporary Table
Extra = Using temporary. MySQL جدول موقت میسازه.
راه: پیچیدگی کوئری رو کم کنید.
LIKE % در ابتدا
Bad: WHERE name LIKE '%محمد%';
Good: WHERE name LIKE 'محمد%';
یا Full-text Search.
OR در WHERE
OR گاهی Index رو نادیده میگیره.
راه: UNION یا refactor.
Function در WHERE
Bad: WHERE YEAR(created_at) = 2026
Good: WHERE created_at >= '2026-01-01' AND created_at < '2027-01-01'
Partitioning
برای جداول خیلی بزرگ، Partition بر اساس تاریخ یا ID.
Denormalization
گاهی Duplicate کردن داده برای سرعت.
Read Replica
Read کوئریها به سرور دوم.
Monitoring
Percona Monitoring
Dashboard رایگان.
New Relic
پولی، عمیق.
Simple: cron
هر شب mysqldumpslow اجرا و ایمیل کنید.
Log Rotation
Slow Log بزرگ میشه. Logrotate تنظیم کنید:
/var/log/mysql/slow.log {
daily
rotate 7
compress
}
Production تنظیمات
long_query_time = 2 (کمتر لاگ)
log_queries_not_using_indexes = 0 (فقط مشکلات جدی)
WordPress نمونه
کوئریهای autoload option معمولاً مشکلدارن. delete_option برای پاک کردن.
Laravel نمونه
N+1 معمولاً. with() برای Eager Loading.
Test در Staging
قبل تغییر production، در Staging تست کنید.
جمعبندی
Slow Query Log کلید بهینهسازی MySQL هست. با تحلیل منظم، مشکلات performance رو پیدا و رفع میکنید.
سباهاست Slow Query Log رو خودکار فعال میکنه.