Wynika to z tego, co nazywam zasadą 5% opartą na kluczowej populacji (liczba krotek).
Jeśli indeksujesz tabelę, w której istnieje krzywa kardynalność, Optymalizator zapytań MySQL zawsze wybierze ścieżkę najmniejszego oporu.
PRZYKŁAD:Jeśli tabela zawiera kolumnę płci, kardynalność wynosi dwa, M i F.
Jaka jest indeksowana taka kolumna płci ??? Zasadniczo otrzymujesz dwie gigantyczne listy z linkami.
Jeśli załadujesz milion wierszy do tabeli z kolumną płci, możesz otrzymać 50% M i 50% F.
Indeks staje się bezużyteczny podczas optymalizacji zapytania, jeśli liczność kombinacji klawiszy (populacja kluczy, jak to sformułowałem) przekracza 5% całkowitej liczby tabel.
Teraz, w odniesieniu do twojego przykładu, dlaczego te dwa różne plany WYJAŚNIJ ??? Domyślam się, że MySQL Query Optimizer i InnoDB jako zespół tagów.
W pierwszym CREATE TABLE tabela i indeksy mają mniej więcej ten sam rozmiar, choć małe, więc zdecydował się na korzyść indeksu, wykonując skanowanie indeksu, a nie pełne skanowanie tabeli . Należy pamiętać, że nieunikalne indeksy zawierają wewnętrzny klucz podstawowy każdego wiersza (RowID) w swoich pozycjach indeksu, dzięki czemu indeksy mają prawie taki sam rozmiar jak sama tabela.
W drugim CREATE TABLE, z powodu wprowadzenia kolejnej kolumny, użytkowniku, sprawiasz teraz, że Optymalizator zapytań widzi zupełnie inny scenariusz:tabela jest teraz większa niż indeksy . W związku z tym Optymalizator zapytań stał się bardziej rygorystyczny w interpretacji sposobu korzystania z dostępnych indeksów. Poszło do zasady 5%, o której wspomniałem wcześniej. Ta reguła nie powiodła się, a Optymalizator zapytań zdecydował się na pełne skanowanie tabeli.