Ciò è dovuto a quella che io chiamo la regola del 5% basata sulla popolazione chiave (cardinalità tupla).
Se indicizzi una tabella in cui esiste una cardinalità sbilenca, MySQL Query Optimizer sceglierà sempre il percorso di minor resistenza.
ESEMPIO:Se una tabella ha una colonna di genere, la cardinalità è due, M e F.
Cosa indicizzi una tale colonna di genere ??? In sostanza ottieni due gigantesche liste collegate.
Se carichi un milione di righe in una tabella con una colonna di genere, potresti ottenere il 50% M e il 50% F.
Un indice è reso inutile durante l'ottimizzazione della query se la cardinalità di una combinazione di chiavi (popolazione di chiavi come l'ho formulata) è superiore al 5% del conteggio totale della tabella.
Ora, per quanto riguarda il tuo esempio, perché i due diversi piani EXPLAIN ??? La mia ipotesi è MySQL Query Optimizer e InnoDB come tag team.
Nella prima CREATE TABLE, la tabella e gli indici sono all'incirca della stessa dimensione anche se piccoli, quindi ha deciso a favore dell'indice eseguendo una scansione dell'indice e non una scansione completa della tabella . Tieni presente che gli indici non univoci portano in giro la chiave primaria interna di ogni riga (RowID) nelle voci dell'indice, rendendo così gli indici quasi della stessa dimensione della tabella stessa.
Nella seconda CREATE TABLE, a causa dell'introduzione di un'altra colonna, utente, ora fai in modo che Query Optimizer veda uno scenario completamente diverso:la tabella ora è più grande degli indici . Pertanto, Query Optimizer è diventato più rigoroso nella sua interpretazione di come utilizzare gli indici disponibili. È andato alla regola del 5% che ho menzionato prima. Questa regola ha fallito miseramente e Query Optimizer ha deciso a favore di una scansione completa della tabella.