INSIA Bases de données SIGL 3 Optimisation – 3 : la

Transcription

INSIA Bases de données SIGL 3 Optimisation – 3 : la
INSIA
Bases de données
SIGL 3
Optimisation – 3 : la commannde Explain
Bertrand LIAUDET
SOMMAIRE
SOMMAIRE
1
LE CALCUL DE COUT ET LA COMMANDE EXPLAIN
1. Principe du passage du SQL au langage impératif.
La jointure indexée
Distinction entre jointure indexée unique (EQ_REF) et jointure indexé multiple
(REF) 3
Pourquoi choisir une solution plutôt qu’une autre ?
Calcul de coût et arbre algébrique indexé
Les restrictions dans les arbres algébriques indexés
2. Présentation générale de la commande EXPLAIN
Présentation de l’explain de MySQL (explain plan sous ORACLE)
Les différents types d’index de l’explain
Tous les Attributs de l’explain
3. Etudes de cas
1 : EXPLAIN de requêtes sans tables
2 : EXPLAIN de requêtes mono-tables sans fonction de groupe
3 : EXPLAIN de requêtes mono-tables avec distinct, fonction de groupe ou order by
4 : EXPLAIN de jointure naturelle - 1
5 : EXPLAIN de jointure naturelle - 2
6 : EXPLAIN de jointure artificielle
7 : EXPLAIN de select imbriqué
4. Autour de l’EXPLAIN
ANALYZE TABLE nomTable
SHOW INDEX
RAPPELS de la syntaxe de création des index
STRAIGHT_JOIN
FORCE INDEX et IGNORE INDEX
3
3
3
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 1/36 - Bertrand LIAUDET
5
6
6
9
9
9
10
11
11
13
15
17
21
23
26
30
30
30
31
32
32
FORCER LE TRI
OPTIMIZE TABLE nomTable
SHOW TABLE STATUS FROM nomBD
BENCHMARK
TP
Utilisation de l’EXPLAIN
Première partie
Deuxième partie : Faire l’arbre algébrique avec coût de tous les EXPLAIN
Troisième partie : Faire l’arbre algébrique avec coût de tous les EXPLAIN
Quatrième partie : Faire l’arbre algébrique avec coût de tous les EXPLAIN
Première édition : mars 2008
Deuxième édition : septembre 2008
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 2/36 - Bertrand LIAUDET
33
33
34
34
35
35
35
35
35
36
LE CALCUL DE COUT ET LA COMMANDE EXPLAIN
1.
Principe du passage du SQL au langage impératif.
Le passage du SQL au langage impératif va essnetiellement mixer l’analyse de l’arbre algébrique
et les possibilités offertes par les index et l’algorithmique des index.
Pour cela, on va définir la jointure indexée qui est une opération d’algorithmique impérative.
La jointure indexée
- opération d’algorithmique impérative
- non commutative
- Principe : on part d’une première table que l’on parcourt entièrement et, pour chaque tuple, on
fait la jointure avec la deuxième table en utilisant un index de cette deuxième table ce qui permet
un accès direct.
Exemple
Si on veut tous les abus avec le nom des buveurs, on fait une jointure indexé entre ABUSER et
les BUVEURS qui consistera à récupérer, pour chaque tuple de ABUSER, le tuple de
BUVEURS correspondant.
Le lien se faisant par NB qui est un attribut indexé de BUVEURS, la recherche sera une
recherche dichotomique. Le nombre d’accès disques pour récupérer les buveurs des abus sera
celui du nombre de tuples dans la table ABUSER.
On a alors une jointure indexée unique.
Distinction entre jointure indexée unique (EQ_REF) et jointure indexé multiple (REF)
Dans l’exemple précédent, on a une jointure indexée unique (EQ_REF dans le vocabulaire de
l’EXPLAIN MySQL) car l’index utilisé est un index unique (index de la clé primaire des
BUVEURS : NB.
Une jointure indexée multiple (REF dans le vocabulaire de l’EXPLAIN MySQL) est une
jointure indexée qui utilise un index multiple (non unique).
Exemple
On veut maintenant tous les abus leur date et avec le nom des buveurs et le cru du vin.
Réponse SQL
Select a.nb, b.nom, a .date, v.nv, v.cru from abuser a, vins v, buveurs b where a.nv=v.nv and
a.nb=b.nb ;
Première solution
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 3/36 - Bertrand LIAUDET
On peut commencer par faire une jointure indexée unique entre ABUSER et BUVEURS puis
une autre jointure indexée unique entre ABUSER et VINS.
Graphe des jointures indexés :
A
date(S)
1
1
B
NB(S)
V
nom(S)
La flèche en pointillé avec un 1 :
NV (S)
Cru (S)
1 : signifie qu’on a une jointure indexée unique.
Arbre algébrique indexé :
Ce type d’arbre est toujours linéaire et utilise des jointures indexées uniques et multiples.
Il n’est pas nécessaire de préciser les projections.
Par contre on précisera les restrictions spécifiques s’il y a lieu.
J( ; NV)
A
J( ;.NB)
Eq_ref
B
Eq_ref
V
Le caractère non commutatif de la jointure et son type unique ou multiple est précisé sur la
branche de la table contenant l’index. EQ_REF pour unique, REF pour multiple.
L’arbre se lit ainsi : on part des ABUSER, on y associe les BUVEURS par jointure indexées
unique puis les VINS par jointure indexées unique.
Deuxième solution
On peut aussi commencer par une jointure indexée multiple entre BUVEURS et ABUSER (car
le NB de ABUSER est indexé en tant que clé primaire) qui sera suivi par une jointure indexée
unique entre ABUSER et VINS. A noter qu’on ne pourrait pas faire une jointure indexée
multiple entre BUVEURS et VINS car le NV de ABUSER n’est pas indexé.
La jointure indexée multiple consiste à partir de la table des BUVEURS, puis à récupérer, pour
chaque tuple de BUVEURS, les tuples de ABUSER correspondant.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 4/36 - Bertrand LIAUDET
Graphe des jointures indexés :
A
N
date(S)
1
B
NB(S)
V
nom(S)
La flèche en pointillé avec un 1 :
La flèche en pointillé avec un N :
NV (S)
Cru (S)
1 : signifie qu’on a une jointure indexée unique.
N : signifie qu’on a une jointure indexée multiple.
Arbre algébrique indexé :
Ce type d’arbre est toujours linéaire et utilise des jointures indexées uniques et multiples.
Il n’est pas nécessaire de préciser les projections.
Par contre on précisera les restrictions spécifiques s’il y a lieu.
J( ; NV)
J( ;.NB)
Ref
A
Eq_ref
V
B
Le caractère non commutatif de la jointure et son type unique ou multiple est précisé sur la
branche de la table contenant l’index. EQ_REF pour unique, REF pour multiple.
L’arbre se lit ainsi : on part des BUVEURS, on y associe les ASSOCIER par jointure indexée
multiple puis les VINS par jointure indexée unique.
Pourquoi choisir une solution plutôt qu’une autre ?
C’est l’optimiseur qui tranche, en fonction des index, des statistiques de la métabase et de son
heuristique.
Le principe général consiste à limiter le nombre d’accès disques, soit, en première
approximation, le nombre de tuples parcourus.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 5/36 - Bertrand LIAUDET
Calcul de coût et arbre algébrique indexé
On va inscrire dans l’arbre algébrique indexé le nombre de tuples récupés dans chaque table.
Première solution
ALL
A (250)
J( ; NV) (250)
Eq_ref (1)
J( ;.NB) (250)
V (50)
Eq_ref (1)
B (100)
Le nombre d’accès diques, en première approximation, sera: 250 + 250*1 + 250*1 = 750
(250 de A + 250 de A * 1 de B + 250 de J(A,B) * 1 de V)
Deuxième solution
J( ; NV)
Ref (2,5)
A (250)
J( ;.NB) (250)
ALL
B (100)
Eq_ref (1)
V (50)
Le 2,5 correspond au nombre moyen de tuples de ABUSER à récupérer à chaque recherche
indexée à partir d’un tuple de BUVEURS : c’est 250/100.
Le nombre d’accès diques, en première approximation, sera: 100 + 100*2,5 + 250*1 = 600
(100 de B + 100 de B * 2,5 de A + 250 de J(A,B) * 1 de V)
Cette solution est donc meilleure que la précédente : ce sera celle proposée par l’EXPLAIN.
Les restrictions dans les arbres algébriques indexés
Exemple
On veut maintenant tous les abus de quantité = 4 avec leur date et avec le nom des buveurs et le
cru du vin.
On pose une sélectivité de 5% pour la restriction quantité=4
Réponse SQL
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 6/36 - Bertrand LIAUDET
Select a.nb, b.nom, a .date, v.nv, v.cru from abuser a, vins v, buveurs b where a.nv=v.nv and
a.nb=b.nb and quantite = 4;
Première solution
On commence par faire une restriction sur ABUSER puis une jointure indexée unique entre
ABUSER et BUVEURS puis une autre jointure indexée unique entre ABUSER et VINS.
Arbre algébrique indexé et calcul de coût
J( ; NV) (12,5)
Eq_ref (1)
J( ;.NB) (12,5)
V (50)
Eq_ref (1)
R(q=4) 5% (12,5) B (100)
ALL
A (250)
Le nombre d’accès diques, en première approximation, sera: 250 + 12,5*1 + 12,5*1 = 300
(250 de A + 12,5 de A restreint * 1 de B + 12,5 de J(A,B) * 1 de V)
Les 250 de A pourrait être ramené à 12,5 si l’attribut quantité était indexé : on obtiendrait alors
37,5 au calcul de coût.
J( ; NV) (12,5)
Eq_ref (1)
J( ;.NB) (12,5)
V (50)
Eq_ref (1)
R(q=4) 5% (12,5) B (100)
Eq_ref (12,5)
A (250)
Deuxième solution
On commence par une jointure indexée multiple entre BUVEURS et ABUSER (car le NB de
ABUSER est indexé en tant que clé primaire) qui sera suivi par une jointure indexée unique
entre ABUSER et VINS.
J( ; NV)
Eq_ref (1)
R(q=4) 5% (12,5) V (50)
J( ;.NB) (250)
Ref (2,5)
A (250)
B (100)
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 7/36 - Bertrand LIAUDET
La restriction à 5 % intervient après chaque accès (par la jointure indexée multiple) aux tuples
de ABUSER correspondant à un tuple de BUVEURS.
Le 2,5 correspond au nombre moyen de tuples de ABUSER à récupérer à chaque recherche
indexée à partir d’un tuple de BUVEURS : c’est 250/100.
Le nombre d’accès diques, en première approximation, sera: 100 + 100*2,5 + 12,5*1 = 362,5
(100 de B + 100 de B * 2,5 de A =250 + 12,5 de J(A,B) * 1 de V)
La restriction n’a pas d’influence sur les accès disques.
Conclusion
Les restrictions sur la table d’index interviennent après la jointure indexée.
Les deux solutions se valent (300 contre 362,5).
L’ajout d’un index rend la première solution nettement plus performante (37, contre 300).
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 8/36 - Bertrand LIAUDET
2.
Présentation générale de la commande EXPLAIN
Présentation de l’explain de MySQL (explain plan sous ORACLE)
•
La commande explain permet d’analyser le plan d’exécution d’une requête.
•
Syntaxe : EXPLAIN requête.
•
Le résultat de la commande est une table qui contient 10 attributs.
•
Chaque ligne concerne une table de la requête analysée.
•
Etant donné le grand nombre d’attributs de la table résultat de l’explain, on utilisera le plus
souvent la présentation « page » (\G) pour faciliter la lecture des résultats.
•
Explain décrit le plan d’exécution de la requête.
•
Il permet de savoir dans quel ordre les traitements sont effectués
•
Il permet aussi de faire un calcul de coût.
•
Explain permet de voir si on peut avoir intérêt à ajouter des index aux tables afin d’obtenir
un select plus rapide.
•
Le principal paramètre du plan d’exécution concerne la gestion des index. L’explain définit
plusieurs types de parcours des tuples, parcours plus ou moins indexés.
Les différents types d’index de l’explain
C’est le quatrième attribut de l’explain qui définit le type de l’index.
Il y a 9 principaux types d’index : ALL, INDEX, RANGE, REF, INDEX_SUBQUERY,
EQ_REF, UNIQUE_SUBQUERY, CONST, SYSTEME.
4 : type
Précise le type de parcours de la table : avec ou sans index, selon le type
d’index.
Liste de la moins bonne à la meilleure :
ALL correspond au moins bon type de parcours : tous les tuples de la table
sont parcourus.
INDEX correspond à un parcours identique à ALL à ceci près que c’est
l’arbre d’index qui est balayé car toutes les informations utiles s’y trouvent.
Les informations utiles sont donc toutes indexées.
RANGE correspond à une recherche sur un intervalle avec un index.
REF correspond à un parcours indexé des tuples avec un index non
unique. Cela correspond généralement à un passage de 1 vers N, de table
jointe à la table maître.
INDEX_SUBQUERY correspond à un parcours identique à REF pour une
sous-requête de type « DEPENDANT_SUBQUERY ».
EQ_REF correspond à un parcours indexé des tuples avec un index
unique. Cela correspond à un passage de 1 vers 1, de la table maître à la
table jointe. C’est le meilleur type de jointure possible.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 9/36 - Bertrand LIAUDET
UNIQUE_SUBQUERY correspond à un parcours identique à EQ_REF
pour une sous-requête de type « DEPENDANT_SUBQUERY ».
CONST correspond à l’usage d’une valeur constante dans la restriction. En
cas de restriction de jointure, cette valeur est remontée dans l’évaluation
d’un select précédent.
SYSTEM correspond au cas rare où une table ne contient qu’une seule
ligne.
Tous les Attributs de l’explain
Le tableau ci-dessous explicite les principales valeurs possibles pour tous les attributs de
l’explain.
Pour avoir toutes les informations : http://dev.mysql.com/doc/refman/5.0/fr/explain.html
1 : id
Identifiant du Select de la requête (qui peut en contenir plusieurs en cas
d’imbrication).
Id vaut NULL pour le résultat des UNION.
2 : select_type
Précise le type de select.
“Simple” est le type le plus courant : requêtes mono-select.
Les autres types concernent les requêtes multi-select.
“Primary” : type du select de la requête principale (requête imbricante
ou première requête de l’union).
“Union” : type du select principal de la ou des requêtes venant après la
première requête de l’union.
“Dependant Subquery” : type du select principal d’une sous-requête de
type imbrication dans le where.
“Derived” : type du select principal d’une sous-requête de type imbriqué
dans le from.
“Dependant union” : type du select principal de la ou des requêtes
venant après la première requête de l’union., la première requête étant de
type « subquery » ou « derived ».
“Union Result” : type de la table résultat d’une union. C’est une table
supplémentaire dans l’EXPLAIN.
3 : table
Nom de la table à laquelle la ligne de l’EXPLAIN se réfère.
4 : type
Précise le type de parcours de la table : avec ou sans index, selon le type
d’index.
5 : possible_keys Indique quels index MySQL peut utiliser.
Pour voir quels index possède une table : show index from table ;
6 : key
Indique quel index MySQL a effectivement utilisé.
7 : key_len
Indique la longueur de la clé de l’index utilisé.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 10/36 - Bertrand LIAUDET
3.
8 : ref
Ref indique le critère d’accès à l’index.
On a une recherche indexée dans la table. La valeur de l’index (6 : key )
peut être comparé à :
« CONST » : une valeur constante.
« attribut » : la valeur d’un attribut d’une autre table qui fait référence à
l’index (6 : key). C’est le cas des jointures.
« FUNC » la valeur d’une expression du select imbriquant. C’est le cas du
select imbriqué.
9 : rows
Estimation du nombre de lignes de la table que MySQL pense devoir
parcourir pour exécuter la requêtes.
10 : extra
Précise différentes informations supplémentaires.
« No tables used » précise qu’il n’y a pas de tables dans le select.
« Using where » précise que le select utilise un where.
« Using index » précise que le select utilise un index.
« Using filesort » signifie qu’il y a un tri (order by et group by).
« Using temporary » signifie qu’il y a un regroupement (distinct et group
by).
Les différents types d’extra peuvent être cumulés.
S’il n’y a pas d’index (possible key et key à NULL) : on peut se demander
si on ne pourrait pas indexer l’attribut du where.
Etudes de cas
1 : EXPLAIN de requêtes sans tables
Explain peut s’appliquer à toutes les requêtes, même celles qui ne contiennent pas de table.
select 4*3;
mysql> select 4*3;
+-----+
| 4*3 |
+-----+
| 12 |
+-----+
1 row in set (0.00 sec)
mysql> explain select 4*3\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
Extra: No tables used
1 row in set (0.00 sec)
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 11/36 - Bertrand LIAUDET
select user();
mysql> select user();
+----------------+
| user()
|
+----------------+
| root@localhost |
+----------------+
1 row in set (0.01 sec)
mysql> explain select user()\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
Extra: No tables used
1 row in set (0.00 sec)
Attributs de l’explain
1 : id
N° du select de l’explain. Il n’y en a qu’un.
2 : select_type
Précise le type de select. “Simple” est le type pour un select mono-table.
10 : extra
Precise différentes informations supplémentaires.
« No tables used » précise qu’il n’y a pas de tables dans le select.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 12/36 - Bertrand LIAUDET
2 : EXPLAIN de requêtes mono-tables sans fonction de groupe
On part de la table suivante :
mysql> show create table emp;
| emp
| CREATE TABLE `emp` (
`NE` int(11) NOT NULL,
`NOM` varchar(10) NOT NULL,
`JOB` enum('PRESIDENT','MANAGER','SALESMAN','CLERK','ANALYST') default
NULL,
`DATEMB` date default NULL,
`SAL` float(7,2) default NULL,
`COMM` float(7,2) default NULL,
`ND` int(11) NOT NULL,
`NEchef` int(11) default NULL,
PRIMARY KEY (`NE`)
) ENGINE=MyISAM
Select * from emp;
mysql> explain select * from emp\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: emp
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14
Extra:
1 row in set (0.01 sec)
Le résultat est le même avec des tables MyISAM sans clé primaire ou en InnoDB avec clés
primaires et clés étrangères.
Attributs de l’explain
3 : table
Précise la table à laquelle la ligne de l’explain se réfère.
4 : type
Précise le type de parcours de la table : avec ou sans index, selon le type
d’index.
ALL correspond au moins bon type de parcours : tous les tuples de la table
sont passés en revue.
9 : rows
Estimation du nombre de lignes de la table que MySQL pense devoir
parcourir pour exécuter la requêtes.
Select * from emp where nd=10
mysql> explain select * from emp where nd=10\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: emp
type: ALL
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 13/36 - Bertrand LIAUDET
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14
Extra: Using where
1 row in set (0.00 sec)
Attributs de l’explain
10 : extra
« Using where » précise que le select utilise un where. Etant donné que par
ailleurs, il n’y a pas d’index (possible key et key à NULL) : on peut se
demander si on ne pourrait pas indexer l’attribut du where.
Alter table emp add index (nd)
On indexe l’attribut “nd”.
mysql> Alter table emp add index (nd) ;
Query OK, 14 rows affected (0.30 sec)
mysql> explain select * from emp where nd=10\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: emp
type: ref
possible_keys: ND
key: ND
key_len: 5
ref: const
rows: 3
Extra:
1 row in set (0.03 sec)
Attributs de l’explain
4 : type
REF correspond à un parcours indexé des tuples avec un index non
unique. Seuls les tuples vérifiant la conditions sont passés en revue.
5 : possible_keys indique quels index MySQL peut utiliser.
6 : key
Indique quel index MySQL a effectivement utilisé.
7 : key_len
Indique la longueur de la clé de l’index utilisé.
8 : ref
« CONST » indique que l’index est comparé à une valeur constante (10
dans l’exemple).
9 : row
On a 3 tuples. Cela correspond à la cardinalité du prédicat : nd=10.
Cette cardinalité est une information de la métabase.
Dans l’explain précédent, on obtient une recherche indexé avec index multiple produisant 3
tuples.
On obtient les mêmes résultat en InnoDB avec déclaration de clé étrangère.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 14/36 - Bertrand LIAUDET
3 : EXPLAIN de requêtes mono-tables avec distinct, fonction de groupe ou order by
Select count(nd) from emp
mysql> explain select count(nd) from emp\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: emp
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14
Extra:
1 row in set (0.00 sec)
Select distinct nd from emp
mysql> explain select distinct nd from emp\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: emp
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14
Extra: Using temporary
1 row in set (0.00 sec)
Select * from emp order by nd
mysql> explain select * from emp order by nd\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: emp
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14
Extra: Using filesort
1 row in set (0.00 sec)
Select nd, count (*) from emp group by job
mysql> explain select job, count(*) from emp group by job\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: emp
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 15/36 - Bertrand LIAUDET
Extra: Using temporary; Using filesort
1 row in set (0.00 sec)
Attributs de l’explain
10 : extra
« Using filesort » signifie qu’il y a un tri (order by et group by).
« Using temporary » signifie qu’il y a un regroupement (distinct et group
by).
Etant donné que par ailleurs, il n’y a pas d’index (possible key et key à
NULL) : on peut se demander si on ne pourrait pas indexer l’attribut de
l’order by, du distinct ou du group by.
Group by sur attribut indexé : select nd, count (*) from emp group by nd
mysql> explain select nd, count(*) from emp group by nd\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: emp
type: index
possible_keys: NULL
key: ND
key_len: 4
ref: NULL
rows: 14
Extra: Using index
1 row in set (0.01 sec)
Attributs de l’explain
4 : type
REF correspond à un parcours séquentiel de l’index : toute l’information (nd)
est dans l’index (nd).
10 : extra
« Using index » signifie qu’il y a un index
Moteur InnoDB
On obtient des résultats facilement interprétables en InnoDB.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 16/36 - Bertrand LIAUDET
4 : EXPLAIN de jointure naturelle - 1
Requête traitée
Tous les employés avec le nom de leur département.
select e.ne, e.nom, d.nd, d.nom
from emp e, dept d
where e.nd=d.n
Version myISAM sans clé primaire
mysql> explain select e.ne, e.nom, d.nd, d.nom from emp e, dept d where
e.nd=d.nd\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: e
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14
Extra:
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: d
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 16
Extra: Using where
2 rows in set (0.00 sec)
Attributs de l’explain
2 : type
Select « SIMPLE » (mono-select), sur les tables « emp » et « dept »
4 : type
type « ALL » : tous les tuples sont parcourus séquentiellement : pour chaque
tuple de la table des employés on parcourt tous les tuples de la tables des
départements. Il n’y a ni a pas d’index.
9 : row
Il faudra parcourir « 14 » * « 16 » rows soit 224 tuples.
10 : extra
« Using where » signifie qu’il y a un where : un attribut qu’on pourrait
indexer : en l’occurrence soit e. ND, soit d.ND.
Version myISAM avec clé primaire
mysql> Explain select e.ne, e.nom, d.nd, d.nom from emp e, dept d where
e.nd=d.n
d\G
*************************** 1. row ***************************
id: 1
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 17/36 - Bertrand LIAUDET
select_type: SIMPLE
table: e
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14
Extra:
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: d
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: empdept.e.ND
rows: 1
Extra:
2 rows in set (0.06 sec)
Attributs de l’explain
4 : type
Type « ALL » : tous les employés sont parcourus séquentiellement. On en
trouve 14.
Pour chaque tuple de la table des employés on a un parcours indexé des
tuples avec un index unique (EQ_REF). Cela correspond à un passage de 1
vers 1, de la table maître à la table jointe. C’est le meilleur type de jointure
possible.
9 : row
Il faudra parcourir « 14 » * « 1 » rows soit 14 tuples.
6 : key
8 : ref
Dans la table d, l’index, c’est la clé primaire (ND) qui fait référence au ND de
la table e. Noter que le ND de la table e n’a pas besoin d’être indexé.
Arbre algébrique indexé correspondant
J-P( ;E.ND=D.ND ; E.NE, E.nom, D.ND, D.nom) (14)
REF (1)
P(E.NE, nom, E.ND) (14)
P(D.ND, D.nom)
ALL
E (14)
D (16)
Version myISAM avec clé primaire et une restriction supplémentaire indexée
Requête
Tous les employés MANAGER avec le nom de leur départements.
select e.ne, e.nom, d.nd, d.nom
from emp e, dept d
where e.nd=d.n
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 18/36 - Bertrand LIAUDET
and job = MANAGER
Version sans indexation de “job”
Si on n’indexe pas « job », on obtient le même résultat que sans restriction : il faut parcourir
tous les tuples de la tables des employés.
Card(E) * Sélectivité(E ; JOB=MANAGER) * 1
JN-P( ;E.ND=D.ND ;V.NV)
EQ_REF (1)
Card(E) * Sélectivité(E ; JOB=MANAGER)
R-P( ; ; ND, nom)
R-P( ; JOB=MANAGER; NE, nom, ND)
ALL
E
D
Dans l’arbre, on montre le nombre de tuples résultats.
Le nombre de tuples parcourus est donné en supprimant la sélectivité dans le cas du ALL, soit :
Card(E).
Version avec indexation de “job”
mysql> alter table emp add index (job);
Query OK, 14 rows affected (0.18 sec)
Enregistrements: 14 Doublons: 0 Avertissements: 0
mysql> explain select e.ne, e.nom, d.nd, d.nom from emp e, dept d where
e.nd=d.nd and e.job = 'MANAGER'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: e
type: ref
possible_keys: JOB
key: JOB
key_len: 2
ref: const
rows: 3
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: d
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: empdeptisam.e.ND
rows: 1
Extra:
2 rows in set (0.03 sec)
Attributs de l’explain
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 19/36 - Bertrand LIAUDET
4 : type
Type « REF » : on parcourt la table des employés avec un index non unique
(REF) sur JOB. On en trouve 3 tuples.
Pour chaque tuple de la table des employés dont le job= « MANAGER », on
a un parcours indexé des tuples avec un index unique (EQ_REF). Cela
correspond à un passage de 1 vers 1, de la table maître à la table jointe. C’est
le meilleur type de jointure possible.
9 : row
Il faudra parcourir « 3 » * « 1 » rows soit 3 tuples.
6 : key
8 : ref
Dans la table e, l’index, c’est JOB fait référence à une valeur constante
(MANAGER)..
Arbre algébrique simplifié correspondant
Card(E) * Sélectivité(E ; JOB=MANAGER) * 1
JN-P( ;E.ND=D.ND ;V.NV)
EQ_REF
Card(E) * Sélectivité(E ; JOB=MANAGER) = 3
R-P( ; ; ND, nom)
R-P( ; JOB=MANAGER; NE, nom, ND)
REF (3)
E
D
Dans l’arbre, on montre à la fois le nombre de tuples parcourus et le nombre de tuples résultats.
Moteur InnoDE
On obtient les mêmes résultats en InnoDB.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 20/36 - Bertrand LIAUDET
5 : EXPLAIN de jointure naturelle - 2
Requête traitée
Tous les employés leurs départements, leurs chefs et le département de leur chefs.
select *
from emp e, dept d, emp echef, dept dchef
where e.nd=d.nd
and e.nechef=echef.ne
and echef.nd=dchef.nd ;
Version myISAM avec clé primaire
mysql> explain select * from emp e, dept d, emp echef, dept dchef where
e.nd=d.nd and e.nechef=echef.ne and echef.nd=dchef.nd\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: e
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14
Extra:
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: echef
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: empdeptisam.e.NEchef
rows: 1
Extra:
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: d
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: empdeptisam.e.ND
rows: 1
Extra:
*************************** 4. row ***************************
id: 1
select_type: SIMPLE
table: dchef
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: empdeptisam.echef.ND
rows: 1
Extra:
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 21/36 - Bertrand LIAUDET
4 rows in set (0.00 sec)
Attributs de l’explain
4 : type
9 : row
Type « ALL » : on parcourt toute la table des employés.
Type « EQ_REF » : pour chaque employé, il y a un accès direct au
département, à son chef et au département de son chef.
EQ_REF caractérise un index unique. Cela correspond à un passage de 1
vers 1, de la table maître à la table jointe. C’est le meilleur type de jointure
possible.
Il faudra parcourir « 14 » * « 1 » * « 1 » * « 1 » rows soit 14 tuples.
Arbre algébrique simplifié correspondant
Card(E) * 1 * 1 * 1
JN-P( ;Echef.ND=Dchef.ND ;*)
EQ_REF (1)
4 : Dchef
Card(E) * 1 * 1
JN-P( ;E.ND=D.ND ;*)
EQ_REF (1)
D
Card(E) * 1
JN-P( ;E.NEchef=Echef.NE ;*)
E (Card(E))
EQ_REF (1)
Echef
Dans l’arbre, on montre à la fois le nombre de tuples parcourus et le nombre de tuples résultats.
Moteur InnoDE
On obtient les mêmes résultats en InnoDB.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 22/36 - Bertrand LIAUDET
6 : EXPLAIN de jointure artificielle
Requête traitée
Tous les employés qui ont le même job qu’un employé du département 20.
select distinct e1.ne, e1.nom
from emp e1, emp e2
where e1.job=e2.job
and e2.nd=20 ;
Version myISAM sans index autre que la clé primaire
mysql> explain select distinct e1.ne, e1.nom from emp e1, emp e2 where
e1.job=e2.job and e2.nd=20\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: e1
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14
Extra: Using temporary
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: e2
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14
Extra: Using where; Distinct
2 rows in set (0.01 sec)
Attributs de l’explain
4 : type
Type « ALL » : on parcourt la table des employés EMP1, et pour chaque
tuple, on parcourt la table des employés EMP2.
9 : row
Il faudra parcourir « 14 » * « 14 » rows soit 196 tuples.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 23/36 - Bertrand LIAUDET
Arbre algébrique simplifié correspondant
Card(E) * Card(E) * selectivité (E ; ND=20) + restriction du distinct
R-P( ; E2.ND=20; job)
Card(E) * Card(E)
JA-P( ;E1.JOB=E2.JOB ; E1.NE, E1.nom, E2.ND)
ALL
Card(E)
Card(E)
P( ; ; NE, nom, job)
R-P( ; ND=20 ; ND, job)
ALL
E1
E2
Version myISAM avec indexation de JOB et ND
mysql> alter table emp add index(job);
Query OK, 14 rows affected (0.19 sec)
Enregistrements: 14 Doublons: 0 Avertissements: 0
mysql> alter table emp add index(nd);
Query OK, 14 rows affected (0.21 sec)
Enregistrements: 14 Doublons: 0 Avertissements: 0
mysql> explain select distinct e1.ne, e1.nom from emp e1, emp e2 where
e1.job=e2.job and e2.nd=20\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: e2
type: ref
possible_keys: JOB,ND
key: ND
key_len: 4
ref: const
rows: 4
Extra: Using temporary
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: e1
type: ref
possible_keys: JOB
key: JOB
key_len: 2
ref: empdeptisam.e2.JOB
rows: 3
Extra: Using where
2 rows in set (0.03 sec)
Attributs de l’explain
4 : type
Type « REF » : on parcourt la table des employés E2 avec un index non
unique (REF) sur ND qui fait référence à une valeur constante. On en trouve
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 24/36 - Bertrand LIAUDET
4 tuples. Pour chaque tuple, on parcourt la table des employés avec un index
non unique (REF) sur JOB qui fait référence à E2.JOB. On en trouve 2
tuples.
9 : row
Il faudra parcourir « 4 » * « 3 » rows soit 12 tuples.
10 : extra
Using temporary signale le distinct.
Anoter : avec la version indexée, l’ordre de parcours des table à changé : on commence par E2
et on finit par E1.
Arbre algébrique simplifié correspondant
Distinct() : Restriction inconnue
4*3
JA-P( ;E1.JOB=E2.JOB ; E1.NE, E1.nom)
REF (3)
Card(E) * Sélectivité(E ; ND=20) = 4
P(; NE, nom, job)
R-P( ; ND=20 ; job)
REF
E2
E1
A noter : la sélectivité de E1 est une sélectivité d’attribut tandis que celle de E2 est une
sélectivité de prédicat. On pourrait aussi faire le calcul avec une sélectivité d’attribut pour E2 :
ce serait moins précis car la sélectivité d’attribut donne seulement une valeur moyenne.
Moteur InnoDE
On obtient les mêmes résultats en InnoDB.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 25/36 - Bertrand LIAUDET
7 : EXPLAIN de select imbriqué
Requête équivalente à une jointure naturelle
Tous les employés MANAGER de CHICAGO
Requête avec jointure
select e.ne, e.nom
from emp e, dept d
where e.nd=d.nd
and job = ‘MANAGER’
and d.ville=’CHICAGO’;
mysql> explain select e.ne, e.nom from emp e, dept d where e.nd=d.nd and
job = 'MANAGER' and d.ville='CHICAGO'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: e
type: ref
possible_keys: JOB
key: JOB
key_len: 2
ref: const
rows: 3
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: d
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: empdeptisam.e.ND
rows: 1
Extra: Using where
2 rows in set (0.00 sec)
9 : row
3* 1 = 3 tuples passés en revue.
Requête imbriquée
select ne, nom
from emp
where job=’MANAGER’
and nd = any (
select nd
from dept
where ville=’CHICAGO’
);
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 26/36 - Bertrand LIAUDET
mysql> explain select ne, nom from emp where job='MANAGER' and
select nd from dept where ville='CHICAGO')\G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: emp
type: ref
possible_keys: JOB
key: JOB
key_len: 2
ref: const
rows: 3
Extra: Using where
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: dept
type: unique_subquery
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: func
rows: 1
Extra: Using where
2 rows in set (0.00 sec)
nd = any (
2 : select_type
DEPENDANT_SUBQUERY : type du select principal d’une sous-requête
de type imbrication dans le where.
4 : type
UNIQUE_SUBQUERY correspond à un parcours identique à EQ_REF
pour une sous-requête de type « DEPENDANT_SUBQUERY ».
EQ_REF correspond à un parcours indexé des tuples avec un index
unique. Cela correspond à un passage de 1 vers 1, de la table maître à la
table jointe. C’est le meilleur type de jointure possible.
8 : ref
« FUNC » indique que l’index est comparé à une valeur d’un select
imbriquant.
9 : row
3* 1 = 3 tuples passés en revue.
Bilan comparé
Le résultat est le même pour cet exemple.
Toutefois, plus généralement, l’usage de la requête imbriquée est plus restrictive : elle interdit la
projection d’attributs du select imbriqué et elle interdit de retravailler le plan d’exécution (l’arbre
algébrique) en fonction des index.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 27/36 - Bertrand LIAUDET
Requête équivalente à une jointure artificielle
Tous les employés qui ont le même job qu’un employé du département 20.
select e1.ne, e1.nom
from emp e1 where e1.job=any (
select e2.job
from emp e2
where e2.nd=10
);
Version myISAM avec JOB et ND indexés
Remarque : on renomme les tables, bien que ce ne soit pas nécessaire, pour s’y retrouver dans
l’EXPLAIN.
mysql> explain Select e1.ne, e1.nom from emp e1 where e1.job=any(select
e2.job from emp e2 where e2.nd=20)\G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: e1
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 14
Extra: Using where
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: e2
type: index_subquery
possible_keys: JOB,ND
key: JOB
key_len: 2
ref: func
rows: 3
Extra: Using where
2 rows in set (0.00 sec)
Version myISAM avec JOB et ND indexés
2 : select_type
DEPENDANT_SUBQUERY : type du select principal d’une sous-requête
de type imbrication dans le where.
4 : type
INDEX_SUBQUERY correspond à un parcours identique à REF pour une
sous-requête de type « DEPENDANT_SUBQUERY ».
REF correspond à un parcours indexé des tuples avec un index non
unique. Cela correspond généralement à un passage de 1 vers N, de table
jointe à la table maître.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 28/36 - Bertrand LIAUDET
8 : ref
« FUNC » indique que l’index est comparé à une valeur d’un select
imbriquant.
9 : row
14 * 3 = 42 tuples passés en revue.
Bilan comparé
Le résultat est moins bon qu’avec une jointure artificielle.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 29/36 - Bertrand LIAUDET
4.
Autour de l’EXPLAIN
ANALYZE TABLE nomTable
Maysql >analyze table nomTable;
http://dev.mysql.com/doc/refman/5.0/fr/analyze-table.html
Equivalent à myisamchk --analyze ou myisamchk -a
Cette opération permet mettre à jour les méta-données (dans la METABASE) : particulièrement
la cardinalité des prédicats.
En utilisant la commande « Analyse table », on va mettre à jour les méta-données :
mysql> analyze table emp;
+-------------+---------+----------+----------+
| Table
| Op
| Msg_type | Msg_text |
+-------------+---------+----------+----------+
| empdept.emp | analyze | status
| OK
|
+-------------+---------+----------+----------+
1 row in set (0.01 sec)
L’opération peut être exécutée manuellement ou régulièrment et automatiquement.
Script de création des commandes d’analyse pour toutes les tables :
Select concat(‘ANALYZE TABLE ’, table_schema, ‘.’, table_name, ‘ ;’)
from information_schema.tables ;
SHOW INDEX
Syntaxe
Show index from nomTable ;
Permet de lister les index d’une table.
http://dev.mysql.com/doc/refman/5.0/fr/show-index.html
Attribut CARDINALITY
L’attribut « CARDINALITY » dans le « SHOW INDEX » donne une approximation du nombre
de valeurs possibles pour un attribut indexé.
Dans l’idéal, la valeur de CARDINALITY vaut exactement le nombre de valeurs possibles pour
l’attribut considéré.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 30/36 - Bertrand LIAUDET
S’il y a trop peu de tuples dans la table, la valeur de CARDINALITY est souvent diminuée.
S’il y a des valeurs à NULL (NULL à yes), la valeur de CARDINALITY est souvent
augmentée.
Dans le cas du moteur InnoDB, la valeur de CARDINALITY est souvent augmentée.
Exemple
mysql> show index from dept\G
*************************** 1. row ***************************
Table: dept
-- nom de la table
Non_unique: 0
-- index unique : CP (0 = faux)
Key_name: PRIMARY
-- nom de l’index
Seq_in_index: 1
-- n° de la colonne dans l'index, début à 1.
Column_name: ND
-- colonne de l’index
Collation: A
-- Façon dont la col. est triée. A:asc.NULL:non trié.
Cardinality: 16
-- nombre de valeurs différentes
Sub_part: NULL
-- nb cara indexés. NULL si col. totalement indexée.
Packed: NULL
-- façon dont la clé est compactée. NULL si pas.
Null:
-- possibilité d’une valeur NULL. Non si rien.
Index_type: BTREE
-- technique d’indexation
Comment:
-- commentaires
*************************** 2. row ***************************
Table: dept
Non_unique: 1
Key_name: NOM
Seq_in_index: 1
Column_name: NOM
Collation: A
Cardinality: 4
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
2 rows in set (0.01 sec)
RAPPELS de la syntaxe de création des index
Syntaxe
Ajouter un index :
ALTER TABLE NomTable ADD INDEX (nomColIndex);
Supprimer un index :
ALTER TABLE NomTable DROP INDEX nomIndex;
A noter que le nom de l’index n’est pas forcément le nom de la colonne de l’index.
A la création de la table :
CREATE TABLE
NE
NOM
JOB
DATEMB
SAL
COMM
ND
EMP (
integer primary key,
varchar(10) not NULL,
enum ('PRESIDENT','MANAGER', 'SALESMAN', 'CLERK', 'ANALYST'),
date,
float(7,2), key(SAL),
float(7,2),
integer not null, foreign key(ND) references DEPT(ND),
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 31/36 - Bertrand LIAUDET
NEchef
integer references EMP, foreign key(NEchef) references EMP(NE)
) TYPE MyISAM;
create index idx_JOB ON EMP(JOB);
Le bilan est la création de 5 index : NE, SAL, ND, NEchef, JOB
restreinte. Ca empire la situation.
STRAIGHT_JOIN
STRAIGHT_JOIN permet de forcer l’ordre des jointures. L’ordre sera celui de la requête.
La syntaxe est celle d’un JOIN qu’on remplace par STRAIGHT_JOIN.
http://dev.mysql.com/doc/refman/5.0/fr/join.html
Forcer l’ordre des jointures permet de forcer l’optimiseur à utiliser certains index.
C’est une pratique similaire au fait de forcer un index : FORCE INDEX
FORCE INDEX et IGNORE INDEX
FORCE_INDEX permet de forcer le fait d’utiliser un index.
IGNORE INDEX permet d’ignorer un index.
La syntaxe est celle d’un JOIN. On précise à la déclaration de la table l’attribut indexé dont on
veut forcer l’usage ou dont on veut éviter l’usage.
Forcer un index peut conduire à revoir l’ordre des jointures.
C’est une pratique similaire au fait de forcer l’ordre des jointures : STRAIGHT_JOIN
Exemple
mysql> explain select * from emp e force index(nd) join dept d on(e.nd=d.nd)
where d.nom = 'SALES'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: d
type: ref
possible_keys: PRIMARY,NOM
key: NOM
key_len: 17
ref: const
rows: 4
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: e
type: ref
possible_keys: ND
key: ND
key_len: 4
ref: empdept.d.ND
rows: 1
Extra:
2 rows in set (0.01 sec)
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 32/36 - Bertrand LIAUDET
Ici le FORCE INDEX peut se justifier pour pouvoir exploiter l’attribut NOM de DEPT qui est
indexé.
FORCER LE TRI
Shell > Myisamchk --sort-records=1 DATADIR/nomDatabase/nomTable
Permet de trier la table “en dur” selon l’index n°1 (numéro de la ligne de l’index récupéré avec
Show index).
Ce tri permettra d’accélérer ensuite les requêtes qui utilise cet index.
Il faut faire un flush pour que la modification soit prise en compte par le client.
Mysql> flush table nomTable
Mysql> select * from nomTable : les tuples apparaissent triés selon l’index.
OPTIMIZE TABLE nomTable
Maysql >optimize table nomTable;
http://dev.mysql.com/doc/refman/5.0/fr/optimize-table.html
OPTIMIZE TABLE permet de réorganiser les tables et particulièrement les emplacements vides.
Choix du type des données
Mieux vaut choisir types compacts.
Mieux vaut choisir des types à taille fixe.
A éviter
Eviter les requêtes imbriquées.
Eviter les DISTINCT et les ORDER BY.
Consultation des statistiques de lecture en cache et sur disques en InnoDB
C:> mysqladmin -uroot -p extended-status
Enter password: ********
+-----------------------------------+-----------+
| Variable_name
| Value
|
+-----------------------------------+-----------+
...
| Innodb_buffer_pool_read_requests | 12958918 |
| Innodb_buffer_pool_reads
| 8875
|
...
Le paramètre pool_read_requests donne le nombre de lecture logique.
Le paramètre pool_reads donne le nombre de lecture physique.
Les chiffres donnent le nombre de pages, sachant qu’une page INNODB a une taille de 16Ko.
Comment éviter les analyses de tables
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 33/36 - Bertrand LIAUDET
http://dev.mysql.com/doc/refman/5.0/fr/how-to-avoid-table-scan.html
SHOW TABLE STATUS FROM nomBD
Permet de connaître l’état de toutes les tables d’une BD.
BENCHMARK
Permet de connaître les capacités de calcul SQL sur la machine qu’on utilise.
Select benchmark(1 000 000, 1+1)
Donne le temps d’exécution de 1 000 000 d’additions simples par MySQL
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 34/36 - Bertrand LIAUDET
TP
Utilisation de l’EXPLAIN
Première partie
1. Expliquer le résultat de l’explain pour la requête suivante : afficher la date du jour.
2. Utiliser la BD BuveursMyISAM.txt. Vérifier le code effectivement pris en compte par le
serveur pour chaque table.
3. Expliquer le résultat de l’EXPLAIN pour la requête : quels sont tous les buveurs ?
4. Expliquer le résultat de l’EXPLAIN pour la requête : quels sont tous les producteurs
bordelais ?
5. Comment optimiser la requête précédente ? Faites l’optimisation et analyser le résultat de
l’EXPLAIN après optimisation.
6. Vérifier que les résultats de l’EXPLAIN sont cohérents avec les données effectivement dans
la BD.
7. Comment mettre à jour à cohérence ? Exécuter la commande et vérifier les conséquences sur
l’EXPLAIN.
8. Expliquer le résultat de l’EXPLAIN pour la requête : quels sont tous les numéros de vins
ayant conduit à des abus
9. Comment optimiser la requête précédente ? Faites l’optimisation et analyser le résultat de
l’EXPLAIN après optimisation.
10. Expliquer le résultat de l’EXPLAIN pour la requête : quel est le nombre d’abus par numéro
de buveurs ?
11. Peut-on optimiser cette requête ?
Deuxième partie : Faire l’arbre algébrique avec coût de tous les EXPLAIN
12. Utiliser la BD EmployesMyISAM.txt.
Traiter la question : tous les employés avec leurs départements, leurs chefs et le département
de leurs chefs et la liste des employés qui travaillent dans un département de même nom. On
affichera CP et CS de chaque table en jeu. Trier les résultats par nom d’employé.
Faire le graphe de la question.
Quelle est la clé primaire de la question.
Expliquer le résultat de l’EXPLAIN.
Quelle amélioration pourrait-on faire ? Faites-la. Relancer l’EXPLAIN.
Troisième partie : Faire l’arbre algébrique avec coût de tous les EXPLAIN
13. Relancer la BD BuveursMyISAM.txt pour repartir d’une BD sans index.
14. Expliquer le résultat de l’EXPLAIN pour la requête : quels sont tous les millésimes 2007 des
producteurs bordelais.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 35/36 - Bertrand LIAUDET
15. Faites l’arbre algébrique simplifié correspondant à l’EXPLAIN. Mettez-y les formules de
calcul de coût.
16. Expliquer le résultat de l’EXPLAIN pour la requête : quels sont tous buveurs ayant abusé en
2007 ?
17. Faites l’arbre algébrique simplifié correspondant à l’EXPLAIN. Mettez-y les formules de
calcul de coût.
18. Expliquer le résultat de l’EXPLAIN pour la requête : quels sont tous les millésimes 2007 des
producteurs bordelais.
19. Faites l’arbre algébrique simplifié correspondant à l’EXPLAIN. Mettez-y les formules de
calcul de coût.
20. Optimiser la requête précédente. Relancer l’EXPLAIN. Que constatez-vous ?
Quatrième partie : Faire l’arbre algébrique avec coût de tous les EXPLAIN
21. Relancer la BD BuveursMyISAM.txt pour repartir d’une BD sans index.
22. Expliquer le résultat de l’EXPLAIN pour la requête : quels sont tous les buveurs ayant bu un
bordeaux de degré égal à 11 degré. On donnera deux versions : une version avec jointures et
une version avec select imbriqués. Que constatez-vous ?
23. Comment optimiser la requête précédente (avec jointures) ? Faites l’optimisation et analyser
le résultat de l’EXPLAIN après optimisation.
24. Faites l’arbre algébrique de l’EXPLAIN précédent. Mettez-y les formules de calcul de coût.
25. Ajouter toutes les clés étrangères. Relancer l’EXPLAIN. Que constatez-vous ?
26. Modifier le script de création de la BD de la façon suivante : passer le moteur en InnoDB,
ajouter les clés étrangères et les index repérés dans l’analyse. Relancer l’EXPLAIN pour la
dernière requêtes. Comparer les résultats avec la version MyISAM.
INSIA - BASES DE DONNÉES – SIGL 3 – Optimisation – Index et Explain - page 36/36 - Bertrand LIAUDET