Bonsoir,
Envoyé par
Xenofexs
Je ne sais pas trop de quoi tu parles avec les statistiques.
Si vous consultez la doc MySQL, vous pourrez décortiquer la partie EXPLAIN...
1) MySQL commence par dire ceci :
EXPLAIN returns a row of information for each table used in the SELECT statement. It lists the tables in the output in the order that MySQL would read them while processing the statement.
Ainsi, dans les cas 1 et 4 (présence du LEFT JOIN), MySQL a commencé par lire la table INSCRIPTION, tandis que dans les autres cas, il a commencé par lire la table PAIEMENT.
2) La colonne Type permet de savoir comment est traitée la jointure. Quand cette colonne prend la valeur « ALL », voici ce que dit MySQL :
ALL A full table scan is done for each combination of rows from the previous tables. This is normally not good if the table is the first table not marked const, and usually very bad in all other cases. Normally, you can avoid ALL by adding indexes that enable row retrieval from the table based on constant values or column values from earlier tables.
Un full table scan est un balayage complet de la table concerné, ce qui n’est pas bon....
Ainsi, quand pour la table INSCRIPTION et pour la table PAIEMENT la colonne Type prend la valeur « ALL », cela veut dire que MySQL balaiera complètement la table INSCRIPTION, puis pour chaque ligne lue, il balaiera l’ensemble des lignes de la table PAIEMENT: on a un splendide produit cartésien, dont MySQL extraira les lignes à retenir.
Si donc INSCRIPTION comporte 7731 lignes et PAIEMENT 7230 lignes, le nombre total de lectures est égal à environ 56^10.6, c’est beaucoup, et ça justifie les 20 secondes...
Quand pour la table INSCRIPTION, la colonne prend la valeur « eq_ref », cela veut dire que pour chaque ligne lue de la table PAIEMENT, MySQL ne lira qu’une ligne de la table INSCRIPTION. Si donc INSCRIPTION comporte 7731lignes et PAIEMENT 7230 lignes, le nombre total de lectures est égal à 7230 +7 331 (le produit a été transformé en somme), c'est-à-dire approximativement 4000 fois moins que dans le cas précédent, mais ça reste fortement améliorable.
3) La colonne possible_keys permet de savoir quel index est utilisé pour l’accès à la table concernée. Dans vos exemples, quand la colonne Type prend la valeur eq_ref, MySQL a utilisé l’index de la clé primaire de la table (INSCRIPTION en l’occurrence).
Mais en ce qui concerne la table PAIEMENT, manifestement, soit elle dépourvue d’index sur la colonne inscription_id, soit il y en a un, mais MySQL n’a pas voulu s’en servir, pour une raison qui reste à trouver : par exemple l’index n’est pas assez filtrant, c'est-à-dire que le nombre de lignes pour lesquelles inscription_id = 1 est très élevé, faisant que MySQL a toutes les chances de devoir aller faire un tour dans l’ensemble des pages affectées à la table.
Pour que l’on connaisse objectivement la situation des index, merci d’exécuter les commandes :
SHOW INDEX FROM cc_inscription
Et surtout :
SHOW INDEX FROM cc_paiement
4) La colonne ref fournit le nom de la table et de la colonne dont MySQL va extraire les valeurs pour accéder à l'autre table qu’i va traiter. Dans votre cas, il s’agit de la colonne inscription_id de la table PAIEMENT, qui sera rapprochée de la colonne inscription_id de la table INSCRIPTION.
Etc.
=>
De tout cela, il ressort clairement, que la colonne inscription_id de la table PAIEMENT devrait être dotée d’un index, tout en sachant que, si cet index existe déjà, MySQL peut le disqualifier, par exemple parce qu’il n’est pas assez filtrant.
Question : combien de lignes de la table PAIEMENT vérifient la condition WHERE inscription_id = 1 ?
Quand on aura tout bien épluché, on se penchera s’il le faut sur le cas du LEFT JOIN qui empêche peut-être l’utilisation des index. Si fonctionnellement la jointure gauche se justifie, il existe des solutions alternatives pour la mettre en oeuvre, du genre de celles auxquelles on avait recours quand cet opérateur n’existait pas encore.
Quand aieeeuuuuu écrit :
Envoyé par
aieeeuuuuu
Est-ce que votre contrainte référentielle entre ces deux tables est déclarée ?
Il a bigrement raison. En effet, sans clé étrangère permettant de garantir cette contrainte, vous pouvez vous retrouver avec des paiements sans inscription...
En outre, pourquoi la colonne inscription_id de la table PAIEMENT peut-elle être marquée NULL ? (Remarque valable pour les autres colonnes de vos tables...)
Partager