sql >> Databasteknik >  >> RDS >> Mysql

Är en MySQL-primärnyckel redan i någon sorts standardordning

Det korta svaret är ja, primärnyckeln har en ordning, alla index har en ordning, och en primärnyckel är helt enkelt ett unikt index.

Som du med rätta sa, bör du inte förlita dig på att data returneras i den ordning som data lagras i, optimeraren är fri att returnera den i vilken ordning den vill, och detta kommer att vara beroende av frågeplanen. Jag ska dock försöka förklara varför din fråga har fungerat i 12 år.

Ditt klustrade index är bara dina tabelldata, och din klustringsnyckel definierar ordningen som den lagras i. Data lagras på bladet, och klustringsnyckeln hjälper roten (och mellannoterna) att fungera som pekare för att snabbt komma till höger blad för att hämta data. Ett icke-klustrat index är en mycket liknande struktur, men den lägsta nivån innehåller helt enkelt en pekare till rätt position på bladet av det klustrade indexet.

I MySQL är primärnyckeln och det klustrade indexet synonyma, så primärnyckeln är ordnad, men de är i grunden två olika saker. I andra DBMS kan du definiera både en primärnyckel och ett klustrat index, när du gör detta blir din primärnyckel ett unikt icke-klustrat index med en pekare tillbaka till det klustrade indexet.

I de enklaste termerna kan du föreställa dig en tabell med en ID-kolumn som är den primära nyckeln, och en annan kolumn (A), din B-Tree-struktur för ditt klustrade index skulle vara ungefär:

Root Node
                                +---+
                                | 1 |
                                +---+
Intermediate Nodes

                    +---+       +---+       +---+
                    | 1 |       | 4 |       | 7 |
                    +---+       +---+       +---+

Leaf
            +-----------+   +-----------+   +-----------+
    ID ->   | 1 | 2 | 3 |   | 4 | 5 | 6 |   | 7 | 8 | 9 |
    A ->    | A | B | C |   | D | E | F |   | G | H | I |
            +-----------+   +-----------+   +-----------+

I verkligheten kommer bladsidorna att vara mycket större, men detta är bara en demo. Varje sida har också en pekare till nästa sida och föregående sida för att det ska vara enkelt att gå igenom trädet. Så när du gör en fråga som:

SELECT ID, A
FROM T
WHERE ID > 5
LIMIT 1;

du skannar ett unikt index så det är mycket troligt att detta kommer att vara en sekventiell genomsökning. Det är dock mycket troligt inte garanterat.

MySQL kommer att skanna rotnoden, om det finns en potentiell matchning kommer den att gå vidare till de mellanliggande noderna, om satsen hade varit något i stil med WHERE ID < 0 då skulle MySQL veta att det inte fanns några resultat utan att gå längre än rotnoden.

När den väl går vidare till den mellanliggande noden kan den identifiera att den måste börja på den andra sidan (mellan 4 och 7) för att börja söka efter ett ID > 5 . Så den kommer att skanna bladet sekventiellt med början på den andra bladsidan, efter att ha identifierat LIMIT 1 den kommer att sluta när den hittar en matchning (i detta fall 6) och returnera denna data från bladet. I ett så enkelt exempel verkar detta beteende vara tillförlitligt och logiskt. Jag har försökt tvinga fram undantag genom att välja ett ID-värde som jag vet är i slutet av en bladsida för att se om bladet kommer att skannas i omvänd ordning, men jag har ännu inte kunnat producera detta beteende, det betyder dock inte det kommer inte att hända, eller att framtida utgåvor av MySQL inte kommer att göra detta i de scenarier jag har testat.

Kort sagt, lägg bara till en beställning med, eller använd MIN(ID) och bli klar med den. Jag skulle inte förlora för mycket sömn genom att försöka fördjupa mig i frågeoptimerarens inre funktioner för att se vilken typ av fragmentering eller dataintervall som skulle krävas för att observera olika ordningsföljder av det klustrade indexet inom frågeplanen.



  1. Hur kan jag ansluta till Oracle-databasen som sysdba med hjälp av bltoolkit?

  2. Hur man regelbundet uppdaterar min lokala DB med ändringar från produktionsdatabasen

  3. Hur man exporterar data från Excel-kalkylblad till SQL Server 2008-tabellen

  4. MySQL - UPDATE-fråga med SET-sats beroende på resultatet av föregående SET-sats