Sie sind auf Seite 1von 27

EXPLAINDemystified

BaronSchwartz
PerconaInc

Outline
WhatisEXPLAIN?
HowMySQLexecutesqueries
HowtheexecutionplanbecomesEXPLAIN
HowtoreverseengineerEXPLAIN
Hopelesslycomplexstuffyou'llneverremember
Cooltricks

EXPLAINDemystified

WhatisEXPLAIN?
ShowsMySQL'sestimatedqueryplan
OnlyworksforSELECTqueries
mysql>explainselecttitlefromsakila.filmwherefilm_id=5\G
***************************1.row***************************
id:1
select_type:SIMPLE
table:film
type:const
possible_keys:PRIMARY
key:PRIMARY
key_len:2
ref:const
rows:1
Extra:
EXPLAINDemystified

Butfirst...
HowdoesMySQLexecutequeries?
SQL=>ParseTree=>ExecutionPlan
ExecutionerlooksatExecutionPlan
ExecutionermakescallstoStorageEngines
MySQLdoesNOTgeneratebytecode!

EXPLAINDemystified

TheExecutionPlan
SELECT...sakila.film
JOINsakila.film_actorUSING(film_id)
JOINsakila.actorUSING(actor_id)
Onewaytodoit

TheMySQLWay(TM)
JOIN

JOIN

film

film_actor

EXPLAINDemystified

JOIN
actor

film

film_actor

actor

WhereEXPLAINcomesfrom

EXPLAINDemystified

GeneratingEXPLAIN
MySQLactuallyexecutesthequery
ButateachJOIN,insteadofexecuting,itfillsthe
EXPLAINresultset
WhatisaJOIN?
EverythingisaJOIN,becauseMySQLalwaysusesnested
loops
EvenasingletableSELECToraUNIONorasubquery

EXPLAINDemystified

TheColumnsinEXPLAIN
id:whichSELECTtherowbelongsto
IfonlyoneSELECTwithnosubqueryorUNION,then
everythingis1
Otherwise,generallynumberedsequentially
Simple/complextypes
simple:thereisonlyoneSELECTinthewholequery
3subtypesofcomplex:subquery,derived,union.
subquery:numberedaccordingtopositioninSQLtext
derived(subqueryintheFROMclause):executedasatemp
table
union:rowsarespooledintoatemptable,thenreadoutwitha
NULLidinarowthatsaysUNIONRESULT
EXPLAINDemystified

TheColumnsinEXPLAIN
simplesubquery

mysql> EXPLAIN SELECT (SELECT 1


FROM sakila.actor LIMIT 1) FROM
sakila.film;
+----+-------------+-------+...
| id | select_type | table |...
+----+-------------+-------+...
| 1 | PRIMARY
| film |...
| 2 | SUBQUERY
| actor |...
+----+-------------+-------+...
EXPLAINDemystified

TheColumnsinEXPLAIN
derivedtable

mysql>EXPLAINSELECTfilm_idFROM
(SELECTfilm_idFROMsakila.film)ASder;
+----+-------------+------------+...
| id | select_type | table
|...
+----+-------------+------------+...
| 1 | PRIMARY
| <derived2> |...
| 2 | DERIVED
| film
|...
+----+-------------+------------+...
EXPLAINDemystified

TheColumnsinEXPLAIN
Union

mysql> EXPLAIN SELECT 1 UNION ALL


SELECT 1;
+------+--------------+------------+...
| id
| select_type | table
|...
+------+--------------+------------+...
| 1
| PRIMARY
| NULL
|...
| 2
| UNION
| NULL
|...
| NULL | UNION RESULT | <union1,2> |...
+------+--------------+------------+...
EXPLAINDemystified

TheColumnsinEXPLAIN
select_typeshowswhetherit'sasimpleorcomplex
select,andwhichtypeofcomplexselect(PRIMARY,
SUBQUERY,DERIVED,UNION,UNIONRESULT)
SpecialUNIONrules:firstcontainedSELECThas
thesametypeastheoutercontext
e.g.thefirstrowinaUNIONcontainedwithinasubquery
intheFROMclausesaysDERIVED

Dependencesanduncacheability
{DEPENDENT,UNCACHEABLE}{SUBQUERY,UNION}
UncacheablereferstotheItem_cache,notquerycache
EXPLAINDemystified

TheColumnsinEXPLAIN
table:thetableaccessed,oritsalias
Morecomplicatedwhenthere'saderivedtable
<derivedN>,whereNisthesubquery'sidcolumn
Alwaysaforwardreference:thechildrowsarelaterinthe
output

AlsocomplicatedbyaUNION
<union1,2,3...>intheUNIONRESULT,wherethe
referencedidsarepartsoftheUNION
Alwaysabackwardsreference:thereferencedidsare
earlierintheoutput
EXPLAINDemystified

AreYouReadyForThis?
+------+----------------------+------------+...
| id
| select_type
| table
|...
+------+----------------------+------------+...
| 1
| PRIMARY
| <derived3> |...
| 3
| DERIVED
| actor
|...
| 2
| DEPENDENT SUBQUERY
| film_actor |...
| 4
| UNION
| <derived6> |...
| 6
| DERIVED
| film
|...
| 7
| SUBQUERY
| store
|...
| 5
| UNCACHEABLE SUBQUERY | rental
|...
| NULL | UNION RESULT
| <union1,4> |...
+------+----------------------+------------+...
EXPLAINDemystified

AreYouReadyForThis?
+------+----------------------+------------+...
| id
| select_type
| table
|...
+------+----------------------+------------+...
| 1
| PRIMARY
| <derived3> |...
| 3
| DERIVED
| actor
|...
| 2
| DEPENDENT SUBQUERY
| film_actor |...
| 4
| UNION
| <derived6> |...
| 6
| DERIVED
| film
|...
| 7
| SUBQUERY
| store
|...
| 5
| UNCACHEABLE SUBQUERY | rental
|...
| NULL | UNION RESULT
| <union1,4> |...
+------+----------------------+------------+...
EXPLAINDemystified

AreYouReadyForThis?
BoundariesofUNION:
+------+----------------------+------------+...
| id
| select_type
|firstid,lastid(backref)
table
|...

+------+----------------------+------------+...
Boundariesof
| 1
| PRIMARY
|DERIVED:every
<derived3> |...
| 3
| DERIVED
| actor
|...
subsequentid(forward
| 2
| DEPENDENT SUBQUERY
| film_actor |...
ref)
| 4
| UNION
| <derived6> |...

>=totheDERIVEDid
| 6
| DERIVED
| film
|...
| 7
| SUBQUERY
| store
|...
| 5
| UNCACHEABLE SUBQUERY | rental
|...
| NULL | UNION RESULT
| <union1,4> |...
+------+----------------------+------------+...

EXPLAINDemystified

Huh?

SQL,IfYouWantToStudy
EXPLAIN
SELECT actor_id,
(SELECT 1 FROM sakila.film_actor
WHERE film_actor.actor_id = der_1.actor_id LIMIT 1)
FROM (
SELECT actor_id
FROM sakila.actor LIMIT 5
) AS der_1
UNION ALL
SELECT film_id,
(SELECT @var1 FROM sakila.rental LIMIT 1)
FROM (
SELECT film_id,
(SELECT 1 FROM sakila.store LIMIT 1)
FROM sakila.film LIMIT 5
) AS der_2;
EXPLAINDemystified

TheColumnsinEXPLAIN
type:thejointype
Really,theaccesstype:howMySQLwillaccessthe
rowstofindresults
Fromworsttobest
ALL,index,range,ref,eq_ref,const,system,NULL

mysql> EXPLAIN SELECT ...


id: 1
select_type: SIMPLE
table: film
type: range
EXPLAINDemystified

TheColumnsinEXPLAIN
possible_keys:whichindexeslookedusefultothe
optimizer
theindexesthatcanhelpmakerowlookupsefficient

key:whichindex(es)theoptimizerchose
theindex(es)theoptimizerchosetominimizeoverallquery
cost
notthesamethingasmakingrowlookupsefficient!
optimizercostmetricisbasedondiskreads

EXPLAINDemystified

TheColumnsinEXPLAIN
key_len:thenumberofbytesoftheindexMySQLwill
use
MySQLusesonlyaleftmostprefixoftheindex
multibytecharactersetsmakebyte!=character

mysql> EXPLAIN SELECT ...


table: film
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 2
EXPLAINDemystified

TheColumnsinEXPLAIN
ref:whichcolumns/constantsfromprecedingtables
areusedforlookupsintheindexnamedinthekey
column
mysql> EXPLAIN
-> SELECT STRAIGHT_JOIN f.film_id
-> FROM sakila.film AS f
->
INNER JOIN sakila.film_actor AS fa
->
ON f.film_id=fa.film_id AND fa.actor_id = 1
->
INNER JOIN sakila.actor AS a USING(actor_id);
...+-------+...+--------------------+---------+------------------------+...
...| table |...| key
| key_len | ref
|...
...+-------+...+--------------------+---------+------------------------+...
...| a
|...| PRIMARY
| 2
| const
|...
...| f
|...| idx_fk_language_id | 1
| NULL
|...
...| fa
|...| PRIMARY
| 4
| const,sakila.f.film_id |...
...+-------+...+--------------------+---------+------------------------+...
EXPLAINDemystified

TheColumnsinEXPLAIN
rows:estimatednumberofrowstoread
foreveryloopinthenestedloopjoinplan
doesn'treflectLIMITin5.0andearlier

NOTthenumberofrowsintheresultset!

mysql> EXPLAIN SELECT * FROM


sakila.film WHERE film_id > 50
rows: 511
Extra: Using where
EXPLAINDemystified

TheColumnsinEXPLAIN
filtered:percentageofrowsthatsatisfyacondition,
in5.1only
inmostcaseswillbe0or100
toocomplicatedtoexplain

EXPLAINDemystified

TheColumnsinEXPLAIN
TheExtracolumn:veryimportant!
Somepossiblevalues
Usingindex:coveringindex
Usingwhere:serverpostfiltersrowsfromstorageengine
Usingtemporary:animplicittemporarytable(forsortingor
groupingrows,DISTINCT)
Noindicationofwhetherthetemptableisondiskorinmemory

Usingfilesort:externalsorttoorderresults
Noindicationofwhetherthisisanondiskfilesortorinmemory
NoindicationofwhichfilesortalgorithmMySQLplanstouse
EXPLAINDemystified

AnExample
mysql> EXPLAIN SELECT film_id FROM
sakila.film WHERE film_id > 50
id: 1
select_type: SIMPLE
table: film
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 2
ref: NULL
rows: 511
Extra: Using where; Using index
EXPLAINDemystified

Demo:VisualExplain
Maatkitincludesatoolcalledmkvisualexplain
ItcanapplytherulesI'veshown(plusmanyothers)
toconstructatreethatmightapproximatethe
executionplan

EXPLAINDemystified

EXPLAINDemystified