Key Takeaways
If you’re wondering how to fix slow MySQL queries, start by identifying bottlenecks with tools like EXPLAIN or the slow query log. Optimize indexes, review JOINs and subqueries, and always check your schema design. Small tweaks often lead to big performance gains.
Why MySQL Queries Get Slow (And Why It Matters)
So you’ve got a MySQL database, and suddenly, queries that used to take milliseconds are crawling like snails. It’s frustrating, right? Understanding how to fix slow MySQL queries isn’t just a task for DBAs—it’s something developers, engineers, and even startup founders should care about.
Poorly optimized queries slow down applications, waste server resources, and drive up hosting costs. Worse, users bounce when apps lag. Let’s walk through practical ways to spot issues and fix them before they drag your project down.
1. Turn On MySQL’s Slow Query Log
Before fixing anything, you’ve got to know what’s broken. Start by enabling the slow query log, which records queries that exceed a time threshold.
How to enable it:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1; -- logs queries taking longer than 1 second
This log will show you which queries are taking the longest and how frequently they occur. You can also specify a file to write them into using slow_query_log_file.

2. Use EXPLAIN to Understand Query Execution
One of the most underused tools in MySQL is the EXPLAIN command. It helps you understand how MySQL executes your query—which indexes are used (or not used), whether filesorts are involved, and how rows are scanned.
Try this:
EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';
If the result shows a table scan (type: ALL), it means MySQL is going row by row—definitely something to fix.
3. Add (or Fix) Indexes
Indexes are your best friends. If you don’t have them where needed, your database will crawl. But too many indexes? That’s bad too.
Best practice: Index fields used in WHERE, JOIN, and ORDER BY clauses.
Let’s say you often run:
SELECT * FROM orders WHERE customer_id = 123;
You’ll want to make sure customer_id is indexed:
CREATE INDEX idx_customer_id ON orders(customer_id);
Be careful: Indexes do slow down writes (INSERTs, UPDATEs), so only create what you need.
4. Optimize JOINs and Subqueries
JOINs can destroy performance if not used carefully. For instance, joining large tables without indexes on the join keys is a common mistake.
Example of a slow JOIN:
SELECT * FROM orders
JOIN customers ON orders.customer_email = customers.email;
If neither orders.customer_email nor customers.email is indexed, this will be slow. Always index the columns used for joining.
Subqueries can also be problematic. Try replacing them with JOINs or derived tables when possible.
5. Reduce the Use of SELECT *
Using SELECT * might be easy, but it fetches all columns—even ones you don’t need. That means more data over the wire, more memory used, and more I/O.
Instead of:
SELECT * FROM users;
Use:
SELECT id, name, email FROM users;
It’s a simple change, but it adds up in performance gains—especially on large datasets.
6. Normalize (or Denormalize) When Needed
Poor schema design often leads to complex and slow queries. If you’re joining too many tables just to get one report, you may be overly normalized.
Conversely, if your tables are full of repeated data, you might want to normalize a bit more.
Evaluate your data structure and strike a balance between read performance and data integrity.
7. Limit Your Results
Queries that return thousands of rows are rarely necessary. Always limit your results when you can.
SELECT id, name FROM users ORDER BY created_at DESC LIMIT 100;
This reduces memory usage and speeds up response times.
8. Use Query Caching (If Appropriate)
MySQL query cache can store SELECT query results in memory, so future calls return faster. However, it’s deprecated in recent MySQL versions (like 8.0). If you’re on an older version, it might help.
Modern apps usually rely on external caching tools like Redis or Memcached, which are much more flexible.
9. Update Your MySQL Version
Performance improvements are built into newer versions of MySQL. If you’re running an older version, consider upgrading.
Check MySQL’s official changelog for performance improvements across versions.
10. Monitor With Tools Like Percona Toolkit or MySQLTuner
Third-party tools offer deeper performance insights:
- Percona Toolkit helps analyze query performance.
- MySQLTuner offers configuration suggestions based on your current usage.
These tools are gold mines for diagnosing root causes of slow queries.
Common Mistakes That Slow Down Queries
| Mistake | Why It’s Bad |
|---|---|
| Missing indexes | Full table scans increase response time |
| Too many indexes | Slows down INSERT/UPDATE operations |
| Using SELECT * | Fetches unnecessary data |
| No LIMIT clause | Wastes memory and bandwidth |
| Poor JOIN logic | Causes MySQL to scan large datasets |
| Unoptimized subqueries | Can trigger unnecessary nested executions |
Practical Example: Speeding Up a Real Query
Before Optimization:
SELECT * FROM products WHERE category = 'Books' AND price < 20;
Problems:
- No index on
categoryorprice - SELECT *
Fix:
CREATE INDEX idx_category_price ON products(category, price);
SELECT id, name, price FROM products WHERE category = 'Books' AND price < 20;
Results came back 5x faster after indexing and removing the SELECT *.
Pros and Cons of Query Optimization Techniques
| Technique | Pros | Cons |
|---|---|---|
| Adding Indexes | Improves query speed | Slows down write operations |
| Using EXPLAIN | Helps understand query execution | Needs some technical knowledge |
| Refactoring Queries | Cleaner, faster queries | Can be time-consuming |
| Query Caching | Reduces load on database | May serve stale data |
| Schema Redesign | Fixes root issues | Involves downtime or migration effort |
FAQ: How to Fix Slow MySQL Queries
1. What is the easiest way to spot slow queries?
Turn on the slow query log in MySQL. It tells you which queries are taking the longest to execute and gives you a place to start.
2. Should I always use indexes?
Not always. Indexes are great for reads but can hurt write performance. Use them wisely—especially on frequently filtered or joined columns.
3. Why is SELECT * bad?
It fetches every column in the table—even ones you don’t need. This increases memory usage and slows down data transfer.
4. What’s better: JOINs or subqueries?
JOINs are generally better for performance when properly indexed. Subqueries can be useful but often lead to nested execution plans.
5. Is query caching still useful?
Not in MySQL 8.0, where it’s removed. Use external caches like Redis instead.
6. How can I simulate bad performance to test fixes?
Use tools like MySQL Benchmark Tool or add delays in test environments.
Final Thoughts
Learning how to fix slow MySQL queries is part detective work, part engineering. Sometimes, a small tweak like adding an index or rewriting a JOIN does the trick. Other times, you’ll need to dig into schema redesign or third-party monitoring tools. Either way, investing time here makes your entire application faster, smoother, and more scalable.
If your database is still sluggish after all of this, consider reaching out to a DBA or using performance services like Percona or PlanetScale to analyze your workload in depth. Performance tuning isn’t just a one-time fix—it’s a habit that pays off.








