Dit komt door wat ik de 5%-regel noem op basis van de sleutelpopulatie (tuple-kardinaliteit).
Als u een tabel indexeert waar scheve kardinaliteit bestaat, zal de MySQL Query Optimizer altijd de weg van de minste weerstand kiezen.
VOORBEELD:Als een tabel een geslachtskolom heeft, is de kardinaliteit twee, M en F.
Wat is je index zo'n geslachtskolom ??? Je krijgt in wezen twee gigantische gelinkte lijsten.
Als u een miljoen rijen in een tabel laadt met een geslachtskolom, krijgt u mogelijk 50% M en 50% F.
Een index wordt onbruikbaar gemaakt tijdens query-optimalisatie als de kardinaliteit van een toetsencombinatie (sleutelpopulatie zoals ik het formuleerde) meer dan 5% van het totale aantal tabellen is.
Nu, met betrekking tot uw voorbeeld, waarom de twee verschillende EXPLAIN-plannen ??? Mijn gok is de MySQL Query Optimizer en InnoDB als een tag-team.
In de eerste CREATE TABLE zijn de tabel en de indexen ongeveer even groot, hoewel klein, dus het besloot in het voordeel van de index door een indexscan uit te voeren en niet een volledige tabelscan . Houd er rekening mee dat niet-unieke indexen de interne primaire sleutel (RowID) van elke rij in de indexitems bevatten, waardoor de indexen bijna dezelfde grootte hebben als de tabel zelf.
In de tweede CREATE TABLE, vanwege de introductie van een andere kolom, gebruiker, laat je de Query Optimizer nu een heel ander scenario zien:de tabel is nu groter dan de indexen . Daarom werd de Query Optimizer strenger in zijn interpretatie van het gebruik van beschikbare indexen. Het ging naar de 5%-regel die ik eerder noemde. Die regel faalde jammerlijk en de Query Optimizer koos voor een volledige tabelscan.