October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
VGSources
Blog

How to Use MySQL Query Profiling to Find and Fix Slow Queries

Find MySQL slow queries without guessing. This practical workflow combines the slow query log, Performance Schema, EXPLAIN, EXPLAIN ANALYZE, evidence-based tuning, and production safety checks.
Length9 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The reliable way to find a slow MySQL query is to measure the same problem in stages: capture a repeatable slow case, inspect its proposed plan with EXPLAIN, measure actual iterator work with EXPLAIN ANALYZE when your version supports it, make one evidence-based change, and run the workload again. The slow query log and Performance Schema show what has happened in real workloads; EXPLAIN predicts how one statement should run; EXPLAIN ANALYZE executes a statement and reports what actually happened.

This workflow avoids guessing at indexes or rewriting queries blindly. It also separates an inefficient plan from a query that is waiting on locks, storage, CPU, or other concurrent work. The examples below use MySQL terminology and commands; adapt file paths, permissions, thresholds, and production change controls to your deployment.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What MySQL query profiling can tell you

“Slow” is a symptom, not a diagnosis. A statement may consume too many rows, choose a poor join order, scan a large table, spend most of its time in one iterator, or have a perfectly reasonable plan but wait for a lock or storage operation. Profiling gives each possibility a different kind of evidence.

Method What it observes Evidence type Granularity Production considerations
Slow query log Statements that exceeded the configured time and examined-row thresholds Historical executions Query statement Usually the lowest-friction way to collect real slow cases; account for log volume and disk use
Performance Schema Instrumented server and application activity, including statement summaries and waits Historical measurements and aggregate workload data Query, stage, and wait Instrumentation choices affect overhead; use it to measure rather than guess
EXPLAIN The optimizer’s proposed access and join plan Estimated execution Plan operation Does not execute the statement
EXPLAIN ANALYZE Actual iterator timing, rows, loops, and comparison with estimates Measured execution Iterator and plan operation Executes the statement, so use a safe test or controlled production procedure

Start with a repeatable use case where performance is demonstrably too slow. Without a stable request, parameter set, and workload context, a single timing can lead you toward a fix that helps one run and harms the normal workload.

Step 1: Capture a repeatable slow case

Use the slow query log for a historical view

The slow query log records statements that take longer than long_query_time and meet the server’s examined-row threshold. It is useful when you do not yet know which statement is responsible, because it preserves evidence from normal application traffic rather than relying on a hand-picked example.

Check the current settings before changing them:

SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
SHOW VARIABLES LIKE 'min_examined_row_limit';

In an environment where you are allowed to change global settings, enable logging and choose a threshold appropriate to the workload:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;

The one-second value is an example, not a universal target. A busy game service may need a much lower threshold to catch latency-sensitive requests, while a batch system may treat a longer statement as normal. Configuration persistence, log destination, permissions, and restart behavior depend on how your MySQL server is managed; verify those details before relying on a temporary setting.

Large logs are difficult to read line by line. The mysqldumpslow utility groups similar statements and can rank them by time, count, or other available sort modes. For example:

mysqldumpslow -s t -t 20 /path/to/slow.log

Use the summarized output to select a query shape and then reproduce it with representative parameter values. Do not optimize a literal statement that is slow only because it contains an unusual one-off value unless that case matters to users.

Use Performance Schema when you need workload and wait data

Performance Schema is MySQL’s built-in instrumentation system for taking real measurements instead of “wild guesses.” It can summarize statement digests, count executions, show rows examined, and expose stage or wait activity. A digest groups structurally similar statements, allowing a high-frequency query to stand out even when individual executions are short.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A statement-summary query can rank workload shapes by total time and examined rows:

SELECT
  DIGEST_TEXT,
  COUNT_STAR,
  SUM_TIMER_WAIT,
  AVG_TIMER_WAIT,
  SUM_ROWS_EXAMINED
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 20;

Use the result to ask two separate questions: which query consumes the most aggregate time, and which query is slow per execution? A frequently executed moderate query can be a larger capacity problem than a rare outlier. Performance Schema wait and stage instruments also help when the plan looks sensible but users still see latency: lock contention, I/O, CPU pressure, and concurrency can dominate execution time outside the optimizer’s row estimates.

Instrumentation is not a license to enable every possible event permanently. Select the statement, stage, and wait data needed for the investigation, observe overhead, and follow your production change process. Begin with the repeatable slow use case, then enable the measurements that can explain it.

Step 2: Inspect the proposed plan with EXPLAIN

MySQL describes EXPLAIN as providing information about how it executes statements. Run it against the exact query shape and representative predicates:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
EXPLAIN SELECT ...;

For a machine-readable plan, request JSON:

EXPLAIN FORMAT=JSON SELECT ...;

Read the plan as a set of decisions rather than as a single “good” or “bad” label.

Access type and chosen index

Check how each table is accessed, which candidate indexes the optimizer considered, and which index it selected. A full table or full index scan is not automatically wrong: scanning a small table can be cheaper than navigating an index. On a large table, however, an unexpected scan is a prompt to examine predicates, data types, and available indexes before forcing a plan.

Estimated rows and filtering

The plan’s row counts are estimates. Compare them across steps and joins. A large estimated intermediate result can make a later operation expensive even if the final result contains only a few rows. The filtering estimate indicates how much of the candidate data is expected to survive a condition; weak selectivity can explain why an index does little work.

Join order, partitions, and extra operations

For multi-table statements, inspect join order and the access path used for every table. A poor order can create exploding intermediate rows. Check partition choices when partitioning is present, and read the Extra information for additional operations such as sorting, temporary processing, or other work that is not obvious from the access type alone.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

JSON output is especially useful when nested plans, cost details, or join relationships are hard to interpret in the traditional tabular format. Save the plan before changing anything so you can compare the optimizer’s decision after each modification.

Step 3: Measure actual work with EXPLAIN ANALYZE

EXPLAIN ANALYZE was introduced in MySQL 8.0.18. It runs the statement and reports estimated cost and rows alongside measurements such as time to first row, iterator execution time, rows returned, and loops. Use it to test whether the optimizer’s assumptions match reality.

EXPLAIN ANALYZE SELECT ...;

The most valuable comparison is estimate versus actual:

  • Estimated rows far below actual rows: statistics may be stale or data may be skewed. Correlated predicates can also make independent estimates unreliable.
  • Actual rows far below estimates: the optimizer may be carrying unnecessary work through later operators, even if the final result is small.
  • High loop counts: a nested operation may be repeating an expensive lookup for every row from an earlier iterator.
  • Most time in one iterator: tune that operator or its input first instead of rewriting the entire statement.

Because the statement executes, treat this command differently from ordinary EXPLAIN. A read query can still consume significant CPU, memory, and I/O. Document the parameter set, run it against a safe copy when possible, and schedule controlled production measurements when isolation is not possible.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Support and syntax vary by deployed MySQL version. The documented feature covers SELECT and, in releases that support them, multi-table UPDATE, DELETE, and TABLE statements. Confirm your server’s version and syntax before using it. Never casually run an analyzed write against production data: use a safe test, a controlled transaction strategy appropriate to the statement, or a production replica where that is operationally valid.

How to interpret the evidence

When estimates are wrong

If actual rows greatly exceed the estimate, first test refreshed statistics:

ANALYZE TABLE your_table;

Re-run EXPLAIN and, where safe, EXPLAIN ANALYZE. If the mismatch remains, investigate skewed values, correlated columns, predicates that hide selectivity, and indexes that do not represent the way the query filters. Statistics refresh is a testable hypothesis, not a guarantee of improvement.

When a large table is scanned

Check whether the predicate can use an index without transformation. Functions or expressions applied to a column, implicit type conversions, and mismatched comparison types can prevent an efficient search. Verify that filter and join columns have suitable indexes and compatible data types. Do not force an index merely to eliminate a scan; compare measured work before and after.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When a join explodes

Use both the estimated and actual row counts at each join boundary. Missing or weak join predicates, an index that supports only one side of the relationship, or a bad join order can multiply rows before later filters reduce them. Fix the source of the multiplication, then measure again.

When the plan looks reasonable but users still wait

Move beyond the optimizer plan. Performance Schema wait and stage data can reveal lock waits, storage latency, CPU saturation, or concurrency effects. A query can have an efficient access path and still be delayed by another session holding a needed resource. In that case, changing indexes may not address the real bottleneck.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Step 4: Apply the smallest evidence-based fix

Change one material factor at a time so the next measurement can be attributed. Typical candidates are:

  • Indexes: add or adjust indexes for selective filter and join columns, considering the predicates’ order and the rows the query actually needs.
  • Predicates: simplify costly conditions and remove expressions that make indexed columns difficult to search.
  • Projection: return only required columns when reducing row and I/O volume matters.
  • Statistics: refresh table statistics when estimates are demonstrably stale or inaccurate.
  • Query shape: reduce unnecessary full scans or intermediate results only after the plan and measurements identify them as the cost center.

Keep the original query, plan, parameter set, schema change, and measured result together. An index that helps one statement can add write cost or change another statement’s plan. Review the broader workload before making a permanent schema change.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Step 5: Re-run and validate the same workload

Repeat the exact capture and measurement sequence after each change:

  1. Run the same representative parameters and workload conditions.
  2. Capture a fresh slow-log or Performance Schema observation.
  3. Compare traditional and JSON EXPLAIN output with the saved baseline.
  4. Use EXPLAIN ANALYZE only in the safe environment and version-supported cases where actual execution data is needed.
  5. Check total response time, rows examined, rows returned, loops, and waits—not just one attractive number.
  6. Observe other important queries and write workload for regressions.

MySQL performance varies with data distribution, cache state, concurrency, hardware, and workload. A small benchmark result is evidence for that test, not a universal improvement percentage. Keep the change only when it improves the target case without creating an unacceptable cost elsewhere.

Production-safe profiling checklist

  • Define the user-facing symptom and a repeatable request or parameter set.
  • Choose historical capture (slow log or Performance Schema) before guessing at a query.
  • Record the MySQL version, schema state, data scale, and relevant configuration.
  • Use EXPLAIN freely for read-only plan inspection; it does not execute the statement.
  • Treat EXPLAIN ANALYZE as a live execution with resource and write risks.
  • Limit instrumentation and monitor its overhead.
  • Change one evidence-backed factor, then rerun the same workload.
  • Check lock, I/O, CPU, and concurrency effects when plan changes do not explain latency.
  • Preserve rollback steps for index, statistics, and query changes.

Where optimizer trace fits

Optimizer trace can provide detail that complements EXPLAIN, especially when you need to understand why an access path or join order was considered. Its format and content are subject to change between MySQL versions, so treat it as diagnostic output tied to the deployed version rather than a stable interface for automation. Use it after the basic evidence—slow case, plan, actual work, and waits—has narrowed the question.

A practical decision path

Use the following order to avoid collecting detail that cannot answer the immediate question:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Unknown culprit: start with the slow query log or Performance Schema digest summaries to identify query shapes from real traffic.
  2. Known statement, unknown plan: run traditional and JSON EXPLAIN and inspect access types, indexes, estimates, joins, partitions, and extra operations.
  3. Estimate uncertainty: run EXPLAIN ANALYZE in a safe, version-supported environment and compare actual rows, loops, and iterator time.
  4. Plan is costly: test the smallest index, predicate, statistics, or query-shape change suggested by the evidence.
  5. Plan is reasonable but latency remains: inspect Performance Schema waits and stages, then investigate locks, I/O, CPU, and concurrency.
  6. Result is improved: validate against the same workload and monitor for regressions before declaring the change complete.

This sequence turns profiling into a controlled experiment: real workload identifies the target, the optimizer plan explains its intended work, actual execution reveals where time and rows are spent, and a repeat measurement decides whether the fix is real.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.