Con INNER JOIN, MySQL generalmente inizia con la tabella con il minor numero di righe. In questo caso, inizia con la tabella finished
e cerca il record corrispondente in saved
utilizzando l'indice su saved.email
.
Per un LEFT JOIN, (escluse alcune ottimizzazioni) MySQL generalmente unisce i record in ordine (a partire dalla tabella più a sinistra). In questo caso, MySQL inizia con la tabella saved
, quindi tenta di trovare ogni record corrispondente in finished
. Poiché non è utilizzabile indice su finished.email
, deve eseguire una scansione completa per ogni ricerca.
Modifica
Ora che hai pubblicato il tuo schema, posso vedere che MySQL sta ignorando l'indice (finished.email
) quando si passa da utf8
a latin1
set di caratteri. Non hai pubblicato i set di caratteri e le regole di confronto per ogni colonna, quindi seguirò il set di caratteri predefinito per la tabella. Le regole di confronto devono essere compatibili affinché MySQL utilizzi l'indice.
MySQL può forzare (aggiornare) un latin1
confronto, che è molto limitato, fino a un utf8
confronto come unicode_ci
(quindi la prima query può utilizzare l'indice su saved.email
aggiornando latin1
confronto in utf8
), ma non è vero il contrario (la seconda query non può utilizzare l'indice su finished.email
poiché non può eseguire il downgrade di un utf8
confronto fino a latin1
).
La soluzione consiste nel modificare entrambe le colonne dell'e-mail con regole di confronto compatibili, forse più facilmente rendendole serie di caratteri e regole di confronto identiche.