Reference · Cheat sheet
The one-page compressed essence: grade any plan by reading five columns in order.
type = how it reaches rows · key = index chosen ·
rows×filtered = rows carried forward · Extra =
warnings. Grade type first, always.
type ladder (best → worst)| type | Meaning |
|---|---|
| system / const | ≤ 1 matching row, read once. PK/unique = constant. |
| eq_ref | One row per join combo via PK / UNIQUE-NOT-NULL. Best join type. |
| ref | Rows matching an index value — non-unique key or leftmost prefix. |
| range | Index range scan (> < BETWEEN IN). |
| index | Full scan of the index tree (often covering; smaller than table). |
| ALL | Full table scan — every row. Usually the thing to fix. |
possible_keys | Indexes MySQL could use. |
key | Index it chose. NULL = a scan. |
key_len | Bytes of the key used — how many prefix columns engaged. |
rows | Estimated rows examined (InnoDB: an estimate). |
filtered | % surviving the WHERE. rows × filtered = rows joined forward. |
Extra — the warningsUsing index | Covering — index alone, no clustered lookup. |
Using where | Filtered after the engine returns rows. |
Using index condition | Index Condition Pushdown. |
Using filesort | Separate sort — index didn't supply order. |
Using temporary | A temp table was built (often GROUP BY / DISTINCT). |
Also: EXPLAIN FORMAT=JSON for full cost detail;
EXPLAIN ANALYZE always uses FORMAT=TREE.
Source: MySQL 8.0 Manual — EXPLAIN Output Format · EXPLAIN ANALYZE · All lessons