An optimizer trace can show why a query executes slowly in MySQL. The trace contains costs of different indexes that are evaluated and reasons why one is chosen over the other.
Traces are per session. Enabling optimizer_trace doesn't affect other sessions.
# Turn tracing on (it's off by default):SET optimizer_trace="enabled=on";# Run querySELECT ...; # See the trace of the querySELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;# When done with tracing, disable it:SET optimizer_trace="enabled=off";Optimizer traces are JSON encoded. Best to copy the structure in a JSON viewer. The trace contains these steps:
join_preparation shows early query rewritesjoin_optimization shows how execution plan is builtcondition_processing basic rewrites in WHERE/ON conditionsref_optimizer_key_uses: Construction of possible ways to do ref and eq_ref accessesrows_estimation: Estimations of index costs, usable and cause can give hints why an index is not usedconsidered_execution_plans: Choice of the join order attaching_conditions_to_tables Once the join order is fixed, parts of the WHERE clause are "attached" to tables to filter out rows as early as possiblejoin_execution shows any optimizations during execution. The optimizer can overwrite an execution plan with heuristics e.g. reconsidering_access_paths_for_index_ordering.