Submitting the form below will ensure a prompt response from us.
Slow MySQL queries usually don’t start as a “database problem.” They start as a product problem: pages load slowly, dashboards feel heavy, background jobs pile up, and timeouts begin to appear as traffic grows. The tricky part is that MySQL can look perfectly “healthy” while a few inefficient queries quietly eat CPU, lock rows, and slow everything down.
The good news is that most slow queries are fixable without changing your entire architecture. You need a structured approach—first identify the real offenders, then fix them using the right combination of indexing, query rewrites, schema improvements, and configuration tuning.
This guide explains how to fix slow MySQL queries, with a practical workflow and code examples you can apply immediately.
A query becomes slow when MySQL has to do too much work to produce a result. That usually happens because of one (or more) of these reasons:
The fix isn’t one magic setting—it’s a systematic diagnosis.
You Might Also Like:
Optimizing slow MySQL queries should never be a trial-and-error exercise. A structured approach helps you identify the real bottlenecks, apply the right fixes, and measure improvements accurately. Instead of randomly tweaking indexes or server settings, follow the systematic steps below to diagnose and resolve performance issues efficiently.
In MySQL, the slow query log is the most direct way to catch offenders.
MySQL config (my.cnf / my.ini):
[mysqld]
slow_query_log=1
slow_query_log_file=/var/log/mysql/mysql-slow.log
long_query_time=1
log_queries_not_using_indexes=1
These logs queries taking more than 1 second and queries not using indexes. Once enabled, you can analyze the log using tools like mysqldumpslow or pt-query-digest.
SHOW FULL PROCESSLIST;
This shows active queries and helps identify ones stuck or running too long.
Before optimizing, run EXPLAIN to see how MySQL executes the query.
EXPLAIN
SELECT user_id, COUNT(*)
FROM orders
WHERE status = 'paid'
GROUP BY user_id;
What to look for:
If you see scans + high rows, you likely need indexing or a query rewrite.
Indexes are the #1 fix, but incorrect indexing can make things worse.
If your query filters by status and groups by user_id, a composite index may help:
CREATE INDEX idx_orders_status_user
ON orders(status, user_id);
Why composite? Because MySQL can use the left-most parts of an index efficiently. If most queries filter on status, putting it first makes sense.
If you join orders to users:
SELECT u.name, o.total
FROM users u
JOIN orders o ON o.user_id = u.id
WHERE o.created_at >= '2026-01-01';
Make sure:
CREATE INDEX idx_orders_user_id ON orders(user_id);
If you only need 3 columns, don’t fetch 20.
Bad:
SELECT * FROM orders WHERE status='paid';
Better:
SELECT id, user_id, total
FROM orders
WHERE status='paid';
This reduces I/O and memory usage.
OR often breaks index usage.
Sometimes rewriting into UNION is faster:
(SELECT id FROM orders WHERE status='paid')
UNION ALL
(SELECT id FROM orders WHERE status='refunded');
This is slow:
SELECT * FROM products WHERE name LIKE '%iphone%';
Because it can’t use a normal index.
Better options:
ALTER TABLE products ADD FULLTEXT(name);
SELECT * FROM products WHERE MATCH(name) AGAINST('iphone');
If your query is:
SELECT id, total
FROM orders
WHERE user_id = 10
ORDER BY created_at DESC
LIMIT 20;
Add an index that matches filtering + sorting:
CREATE INDEX idx_orders_user_created
ON orders(user_id, created_at);
This becomes slow:
SELECT * FROM orders ORDER BY id LIMIT 20 OFFSET 200000;
Better: keyset pagination:
SELECT * FROM orders
WHERE id < 500000
ORDER BY id DESC
LIMIT 20;
This scales far better.
If reads and writes block each other, even well-indexed queries feel slow.
Things to check:
Quick visibility:
SHOW ENGINE INNODB STATUS;
If you see lock waits, focus on:
Configuration helps, but only after query/index improvements.
Common high-impact settings (varies by workload):
Check current values:
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW VARIABLES LIKE 'tmp_table_size';
Also, check if your server is I/O bound:
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';
If reads from disk are high, the buffer pool might be too small, or queries are scanning too much.
If you need impact fast, focus on:
When MySQL slows down, the real solution is rarely just “add an index.” It’s usually a combination of query design, schema planning, caching strategy, and infrastructure tuning.
Moon Technolabs helps teams:
Moon Technolabs helps businesses diagnose, optimize, and scale MySQL databases with performance tuning, indexing strategies, and production-ready solutions.
Fixing slow MySQL queries is about being methodical: measure first, then optimize the right layer. Start with identifying slow queries, validate execution plans with EXPLAIN, add appropriate indexes, rewrite expensive patterns, and only then tune the server configuration.
If you follow this approach, you’ll see measurable gains—faster pages, fewer timeouts, and a database that scales smoothly as your product grows.
Submitting the form below will ensure a prompt response from us.