
You hit refresh on a slow dashboard query and watch the seconds tick. The fix isn’t a hardware upgrade—it’s a combination of logging, analysis, and index tuning that MySQL already supports, yet the default long_query_time sits at 10 seconds (CoderPad (development blog)) with the slow query log switched off (Percona (MySQL consulting)), meaning many sluggish queries slip by unnoticed.
MySQL default long_query_time: 10 seconds ·
Slow query log status by default: disabled ·
EXPLAIN output rows examined: shows full table scan when no index ·
Query speed improvement with proper indexing: up to 100x ·
MySQL Performance Schema overhead: less than 1% CPU typically
Quick snapshot
- Enabling slow query log captures queries exceeding
long_query_time(Percona (MySQL consulting)) - EXPLAIN shows execution plan including rows scanned and possible keys (MySQL official documentation)
- Proper indexing can speed up queries up to 100× (Percona (MySQL performance))
- Performance Schema overhead typically less than 1% CPU (Severalnines (database operations))
- Exact performance impact of Performance Schema on high-write workloads is not well documented in benchmarks
- Whether
WHERE INwith bind parameters uses indexes optimally across all MySQL versions
- Enable slow query log and set threshold
- Use EXPLAIN to analyze captured queries
- Create or adjust indexes based on execution plan
- Monitor with Performance Schema for continuous tuning
- Automate slow query analysis with pt-query-digest (Percona (MySQL consulting))
- Regularly update MySQL for optimizer improvements (GeeksforGeeks (tutorials))
- Combine Performance Schema with traditional logs for a complete picture
Five configuration details define where many MySQL speed searches begin.
| Configuration | Value |
|---|---|
| Default slow_query_log state | OFF |
| Default long_query_time | 10.000000 seconds |
| EXPLAIN type for full table scan | ALL |
| MAX possible key length for InnoDB index | 767 bytes (or 3072 with large_prefix) |
| Performance Schema enabled by default since | MySQL 5.6.4 |
How to enable slow query logging in MySQL?
Setting the long_query_time threshold
- Set
SET GLOBAL long_query_time = 2to capture most slow queries (default is 10 seconds, CoderPad (development blog)) - For debugging, set to 0 to log every query temporarily
- Value is in seconds and supports fractional (e.g., 0.1)
Enabling the slow_query_log variable
- Run
SET GLOBAL slow_query_log = 1to switch on logging (GeeksforGeeks (tutorials)) - Must be placed in
my.cnffor persistence:slow_query_log=ON - File-based logging is default; performance impact is minimal
Choosing the log output destination
- Set
log_output = FILE(default) orTABLE(writes tomysql.slow_log) - File output is easier to rotate and parse with pt-query-digest
- Table output is convenient for
SELECTqueries on the log
A DBA who leaves long_query_time at 10 seconds will miss most application slowdowns. Dropping it to 2 seconds (or lower) surfaces the real trouble spots without overwhelming the system.
The catch: Enabling the slow query log on a high-throughput production server may cause slight I/O pressure, but the value of catching a single runaway query far outweighs the overhead.
How to analyze slow queries using EXPLAIN?
Reading EXPLAIN output columns
type– access method;ALLmeans full table scan (MySQL official documentation)rows– estimated rows examined; high numbers signal inefficiencyExtra– often showsUsing filesortorUsing temporaryas red flags
Identifying full table scans
- When
type = ALLappears, MySQL is scanning every row – a clear sign that no index is being used (Percona (MySQL consulting)) - Check
possible_keysandkey: ifpossible_keysis non-NULL butkeyis NULL, index is not used
Detecting missing or unused indexes
- If
keyisNULLor different frompossible_keys, the optimizer chose a different path - Missing indexes on
WHEREcolumns are the most common cause of slowSELECTqueries (MySQL official documentation) - Use
SHOW INDEX FROM tableto verify existing indexes
What this means: A single EXPLAIN quickly separates queries that need indexing from those that need rewriting. The pattern is consistent: if rows exceeds the table row count you expect, add an index.
How to optimize indexes to speed up MySQL queries?
Creating composite indexes for WHERE and JOIN
- Place the most selective column first (leftmost prefix rule) (Percona (MySQL performance))
- Composite indexes on
(product_id, order_date)can accelerate many e‑commerce queries - Columns used in
WHEREshould be indexed beforeORDER BYcolumns
Avoiding over-indexing
- Too many indexes slow down
INSERT/UPDATEand consume disk space - Monitor index usage with
performance_schema.table_io_waits_summary_by_index_usage - Remove unused indexes after analysis
Using covering indexes
- When all selected columns are part of the index,
ExtrashowsUsing index– no table access needed (Percona (MySQL consulting)) - Covering indexes can eliminate disk I/O entirely, offering the biggest speed gains
- Design them for the most frequent read queries
The trade-off: Indexes speed reads but slow writes. For read-heavy applications the balance heavily favours indexing, but write-heavy tables require careful selectivity analysis.
How to fix common slow query patterns like WHERE IN and SELECT *?
Why WHERE IN can be slow with large lists
- MySQL may not use an index efficiently when the IN list contains hundreds or thousands of values (Percona (MySQL consulting))
- Consider breaking into batches of 100–200 IDs or using a temporary table
- Use
EXISTSorJOINinstead of subqueries with IN
Rewriting SELECT * to select only needed columns
- SELECT * forces MySQL to read all columns, increasing I/O and network transfer (GeeksforGeeks (tutorials))
- Explicitly list the columns required – often 3–5 instead of 30
- Also helps covering indexes work because they don’t include unnecessary fields
Using EXISTS or JOIN instead of IN for subqueries
- MySQL often handles
EXISTSandJOINmore efficiently thanIN - Rewrite
WHERE id IN (SELECT id FROM orders WHERE ...)asJOIN orders ON ... - Check the rewritten query with EXPLAIN – both should be tested
The same WHERE IN that kills performance on large lists works fine on small ones. The fix isn’t avoiding IN entirely – it’s knowing your data size and using a threshold (e.g., 200 items) to switch tactics.
Why this matters: In PHP applications, many slow MySQL queries come from poorly constructed ORM calls that generate SELECT * or huge IN lists. Fixing these patterns often cuts query time from seconds to milliseconds without touching indexes.
How to use MySQL Performance Schema for query analysis?
Enabling Performance Schema
- Enabled by default since MySQL 5.6.4 (Severalnines (database operations))
- Can be toggled at startup with
performance_schema=ONinmy.cnf - Overhead is minimal – typically less than 1% CPU
Querying events_statements_summary_by_digest
- This table aggregates queries by normalized digest, showing total wait time, count, and average latency (Severalnines (database operations))
- Times are in picoseconds – divide by 1e12 for seconds
- Sort by
SUM_TIMER_WAITto find the most expensive queries
Identifying high-load queries without log files
- Use
sys.statement_analysisview (part of sys schema) for a simpler interface - No need to enable slow query log for analysis – Performance Schema runs continuously
- Ideal for environments where log file management is constrained
The pattern: Performance Schema provides a real-time, zero‑maintenance alternative to the slow query log. For most teams, combining both gives the most complete picture: the log for history and schema for current load.
Clarity check
- Enabling slow query log allows capture of queries exceeding
long_query_time - EXPLAIN provides query execution plan
- Indexes reduce row scanning significantly
- Exact performance impact of Performance Schema on high-write workloads varies by workload type
- Whether
WHERE INwith bind parameters uses indexes optimally across all MySQL versions depends on optimizer version
“The slow query log is the starting point for any tuning exercise. Without it, you’re guessing.”
— Percona (MySQL consulting), 2024
“Using EXPLAIN on a representative query tells you exactly where the optimizer is spending time. The output is often more valuable than guessing which index to add.”
— MySQL official documentation (select-optimization)
For developers and DBAs who invest an hour in this diagnostic workflow, the payoff is consistent. Queries that once forced page loads to crawl can be reduced from seconds to milliseconds – often with a single composite index or a query rewrite. The choice to ignore the slow query log or skip EXPLAIN means accepting that every user will wait a little longer. For a PHP application handling thousands of requests per minute, that latency accumulates into real revenue loss and user frustration.
For the team managing a MySQL‑backed service, the implication is clear: set long_query_time to 2 seconds, enable the slow query log, run EXPLAIN on the worst offenders, and build indexes that match the WHERE clauses. The alternative is a database that grows slower with every new feature.
percona.com, geeksforgeeks.org, percona.com, geraldvillorente.com, releem.com, coderpad.io, severalnines.com
Frequently asked questions
What is the default long_query_time in MySQL?
10 seconds. You can change it with SET GLOBAL long_query_time = <value> (CoderPad (development blog)).
How to set slow_query_log globally?
Execute SET GLOBAL slow_query_log = 1. For persistence, add slow_query_log=ON to my.cnf (GeeksforGeeks (tutorials)).
Does indexing always speed up queries?
No. Indexing speeds up SELECT queries but adds overhead to INSERT/UPDATE operations. Over‑indexing can degrade write performance and consume disk space.
What is the difference between EXPLAIN and EXPLAIN ANALYZE?
EXPLAIN shows the estimated execution plan. EXPLAIN ANALYZE (MySQL 8.0.18+) runs the query and provides actual timings and rows examined (MySQL official documentation).
How to log queries slower than 1 second in MySQL?
Set SET GLOBAL long_query_time = 0.5 (or any value less than 1). Ensure slow_query_log is ON (Gerald Villorente Blog (community)).
Can Performance Schema cause performance degradation?
In most cases overhead is less than 1% CPU. On extremely high‑write workloads with many concurrent connections the overhead may be slightly higher, but it remains negligible for typical applications (Severalnines (database operations)).
What does ‘Using filesort’ mean in EXPLAIN output?
It means MySQL must sort the result set using an extra pass, often because no index covers the ORDER BY clause. Adding a composite index on the WHERE + ORDER BY columns can eliminate filesorting.