Avec INNER JOIN, MySQL commencera généralement par la table avec le plus petit nombre de lignes. Dans ce cas, il commence par la table finished
et recherche l'enregistrement correspondant dans saved
en utilisant l'index sur saved.email
.
Pour un LEFT JOIN, (à l'exception de certaines optimisations), MySQL joint généralement les enregistrements dans l'ordre (en commençant par la table la plus à gauche). Dans ce cas, MySQL démarre avec la table saved
, puis tente de trouver chaque enregistrement correspondant dans finished
. Puisqu'il n'y a pas d'éléments utilisables index sur finished.email
, il doit effectuer une analyse complète pour chaque recherche.
Modifier
Maintenant que vous avez posté votre schéma, je peux voir que MySQL ignore l'index (finished.email
) en passant de utf8
en latin1
jeu de caractères. Vous n'avez pas publié les jeux de caractères et les collations pour chaque colonne, donc je vais par le jeu de caractères par défaut pour la table. Les classements doivent être compatibles pour que MySQL puisse utiliser l'index.
MySQL peut contraindre (mettre à niveau) un latin1
classement, qui est très limité, jusqu'à un utf8
classement tel que unicode_ci
(ainsi la première requête peut utiliser l'index sur saved.email
en mettant à jour latin1
classement en utf8
), mais l'inverse n'est pas vrai (la deuxième requête ne peut pas utiliser l'index sur finished.email
car il ne peut pas rétrograder un utf8
classement jusqu'à latin1
).
La solution consiste à remplacer les deux colonnes d'e-mail par un classement compatible, peut-être plus facilement en leur donnant des jeux de caractères et des classements identiques.