๐Ÿ” MySQL EXPLAIN Plan Analysis โ€“ Understand & Optimize Your Queries


๐Ÿงฒ Introduction โ€“ Why Use EXPLAIN in MySQL?

The EXPLAIN command in MySQL reveals how your query will be executedโ€”which indexes will be used, how tables will be joined, and how many rows will be scanned. Itโ€™s an essential tool for debugging slow queries, optimizing joins, and verifying that indexes are effective.

๐ŸŽฏ In this guide, youโ€™ll learn:

  • How to use EXPLAIN and EXPLAIN ANALYZE
  • Column-by-column breakdown of the output
  • Real-world use cases for performance tuning
  • What to fix and how to fix it
  • Best practices for using EXPLAIN with JOINs, subqueries, and sorting

โš™๏ธ Basic Syntax

EXPLAIN SELECT * FROM orders WHERE customer_id = 123;

โœ… With Execution Time (MySQL 8+):

EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 123;

๐Ÿ“Š EXPLAIN Output Columns Breakdown

ColumnDescription
idQuery part identifier (higher = deeper in nesting)
select_typeType of SELECT (e.g., SIMPLE, PRIMARY, SUBQUERY)
tableTable being accessed
typeJoin type (ALL, index, range, ref, eq_ref, const, system)
possible_keysIndexes that may apply
keyIndex actually used
key_lenLength of the index used
refColumns or constants used to select rows with the index
rowsEstimated rows examined
filteredEstimated % of rows filtered by conditions
ExtraAdditional info (e.g., Using where, Using temporary, Using filesort)

๐Ÿง  Understanding type โ€“ The Most Important Column

TypeMeaningPerformance
systemTable has only one rowโœ… Best
constSingle row match by indexโœ… Best
eq_refOne row per row lookup (primary key)โœ… Great
refJoin via indexed column with non-unique keyโœ… Good
rangeRange search using index (BETWEEN, >, <)โœ… Efficient
indexFull scan of indexโš ๏ธ Okay
ALLFull table scanโŒ Bad

๐Ÿ“ˆ Sample EXPLAIN Output

EXPLAIN SELECT * FROM orders WHERE customer_id = 123;
idselect_typetabletypepossible_keyskeyrowsExtra
1SIMPLEordersrefcustomer_idcustomer_id10Using where

๐Ÿง  Interpretation:

  • โœ… Good: Index on customer_id used
  • ref: Means efficient indexed lookup
  • rows = 10: Only 10 rows expected to be scanned

๐Ÿ”€ Example with JOINs

EXPLAIN SELECT o.id, c.name 
FROM orders o 
JOIN customers c ON o.customer_id = c.id 
WHERE o.order_date > '2024-01-01';

๐Ÿ” Watch for:

  • type = ref or eq_ref on JOIN
  • key should be not NULL
  • Avoid ALL scans on joined tables

๐Ÿšจ Common Red Flags in Extra Column

FlagMeaning
Using filesortMySQL must sort results in memory โ€” needs optimization or index
Using temporaryUses temporary tables (e.g., for GROUP BY, DISTINCT) โ€” optimize queries
Using whereFilter applied after fetch โ€” normal for selective queries
Using indexCovered by index (no table row access) โ€” very efficient

๐Ÿงช Use EXPLAIN ANALYZE (MySQL 8+)

EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 123;

Returns the execution plan with actual run-time metrics, including:

  • Execution time per operation
  • Loops
  • Number of rows examined vs returned

๐Ÿงฑ Best Practices for EXPLAIN Optimization

โœ… Avoid ALL type โ€” means full table scan
โœ… Use EXPLAIN on all slow queries
โœ… Check that indexes are being used (key not NULL)
โœ… Add indexes on JOIN and WHERE columns
โœ… Avoid functions on indexed columns (e.g., YEAR(date_column) in WHERE)
โœ… Check rows count to ensure minimal data scan
โœ… Use LIMIT and ORDER BY on indexed fields when paginating


โš™๏ธ EXPLAIN with Advanced Queries

๐Ÿงฉ Subqueries

EXPLAIN SELECT * FROM users WHERE id IN (SELECT user_id FROM orders);

๐Ÿ“Œ Consider using a JOIN instead of a subquery for better performance.


๐Ÿงช GROUP BY + HAVING

EXPLAIN SELECT department, COUNT(*) FROM employees GROUP BY department HAVING COUNT(*) > 10;

๐Ÿ“Œ Add indexes on the GROUP BY column to avoid temp tables and filesorts.


๐Ÿ“Œ Summary โ€“ Recap & Next Steps

The EXPLAIN and EXPLAIN ANALYZE commands are your primary tools for diagnosing slow queries and understanding how MySQL executes them. Use them consistently to optimize queries and indexes.

๐Ÿ” Key Takeaways

  • Use EXPLAIN to see execution plans before running queries
  • Look for type, key, rows, and Extra info
  • Avoid full table scans (ALL) and filesorts where possible
  • Use EXPLAIN ANALYZE in MySQL 8+ for real execution time

โš™๏ธ Real-World Relevance
Developers and DBAs rely on EXPLAIN to optimize APIs, reports, dashboards, and background tasks using MySQL at scale.


โ“ FAQ โ€“ MySQL EXPLAIN Plan

โ“ What’s the difference between EXPLAIN and EXPLAIN ANALYZE?
โœ… EXPLAIN shows estimated plans, EXPLAIN ANALYZE shows actual runtime execution (MySQL 8+).

โ“ Why is my query using type = ALL?
โœ… MySQL is performing a full table scanโ€”likely missing an index. Add an index on filtered/joined column.

โ“ How can I improve Using filesort?
โœ… Add appropriate ORDER BY indexes or simplify sorting logic.

โ“ What if key is NULL in EXPLAIN?
โœ… No index is used. Check possible_keys and create one if necessary.

โ“ Should I always add indexes if ALL is shown?
โœ… Usually yes, but analyze the use caseโ€”small tables may not need indexing.


Share Now :

Leave a Reply

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

Share

๐Ÿ” MySQL EXPLAIN Plan Analysis

Or Copy Link

CONTENTS
Scroll to Top