sql >> Database teknologi >  >> RDS >> Mysql

MySQL EXPLAIN 'type' ændres fra 'range' til 'ref', når datoen i where-sætningen ændres?

Forskellige søgestrategier giver mening for forskellige data. Især skal indeksscanninger (såsom rækkevidde) ofte søge for rent faktisk at læse rækken. På et tidspunkt er det langsommere at udføre alle disse søgninger end slet ikke at bruge indekset.

Tag et trivielt eksempel, en tabel med tre kolonner:id (primær nøgle), navn (indekseret), fødselsdag. Sig, at den har mange data. Hvis du beder MySQL om at lede efter Bobs fødselsdag, kan den gøre det ret hurtigt:Først finder den Bob i navneindekset (dette tager et par søgninger, log(n) hvor n er rækkeantallet), derefter en ekstra søgning for at læs selve rækken i datafilen og læs fødselsdagen ud fra den. Det er meget hurtigt og langt hurtigere end at scanne hele bordet.

Overvej derefter at lave et name like 'Z%' . Det er nok en ret lille del af bordet. Så det er stadig hurtigere at finde, hvor Z'erne starter i navneindekset, og søg derefter datafilen for hver enkelt for at læse rækken. (Dette er en rækkeviddescanning).

Overvej endelig at bede om alle navne, der begynder med M-Z. Det er nok omkring halvdelen af ​​dataene. Den kunne lave en rækkeviddescanning og derefter en masse af søgninger, men at søge tilfældigt over datafilen med det ultimative mål at læse halvdelen af ​​rækkerne er ikke optimalt:det ville være hurtigere blot at lave en stor sekventiel læsning over datafilen. Så i dette tilfælde vil indekset blive ignoreret.

Dette er, hvad du ser – undtagen i dit tilfælde er der en anden nøgle, den kan falde tilbage på. (Det er også muligt, at det faktisk kan bruge datoindekset, hvis det ikke havde det andet, det skulle vælge det indeks, der vil være hurtigst. Vær opmærksom på, at MySQL's optimizer ofte laver fejl i dette.)

Så kort sagt forventes dette. En forespørgsel siger ikke hvordan for at hente dataene, står der snarere hvad data at hente. Det er meningen, at databasens optimering skal finde den hurtigste måde at hente den på.

Du kan finde et indeks på begge kolonner, i rækkefølgen (public_key,created_on_date) foretrækkes i begge tilfælde, og fremskynder din forespørgsel. Dette skyldes, at MySQL kun kan bruge ét indeks pr. tabel (pr. forespørgsel). Datoen går også til sidst, fordi en rækkeviddescanning kun kan udføres effektivt på den sidste kolonne i et indeks.

[InnoDB har faktisk et andet lag af indirekte, tror jeg, men det ville bare forvirre pointen. Det gør ikke en forskel for forklaringen.]




  1. Vil GETUTCDATE() returnere den samme værdi, hvis den bruges to gange i den samme sætning?

  2. FEJL ved afsendelse af tabel som parameter i MySQL-lagerprocedure

  3. OPTION (GENKOMPILER) er altid hurtigere; Hvorfor?

  4. oracle systimestamp (sysdate) til millisekunder