Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Ist ein MySQL-Primärschlüssel bereits in einer Art Standardreihenfolge

Die kurze Antwort lautet ja, der Primärschlüssel hat eine Reihenfolge, alle Indizes haben eine Reihenfolge und ein Primärschlüssel ist einfach ein eindeutiger Index.

Wie Sie richtig gesagt haben, sollten Sie sich nicht darauf verlassen, dass die Daten in der Reihenfolge zurückgegeben werden, in der sie gespeichert sind. Der Optimierer kann sie in beliebiger Reihenfolge zurückgeben, und dies hängt vom Abfrageplan ab. Ich werde jedoch versuchen zu erklären, warum Ihre Anfrage seit 12 Jahren funktioniert.

Ihr gruppierter Index besteht nur aus Ihren Tabellendaten, und Ihr Gruppierungsschlüssel definiert die Reihenfolge, in der sie gespeichert werden. Die Daten werden auf dem Blatt gespeichert, und der Gruppierungsschlüssel hilft der Wurzel (und Zwischennotizen), als Zeiger zu fungieren, um schnell dorthin zu gelangen rechtes Blatt, um die Daten abzurufen. Ein Nonclustered-Index ist eine sehr ähnliche Struktur, aber die unterste Ebene enthält einfach einen Zeiger auf die richtige Position auf dem Blatt des Clustered-Index.

In MySQL sind der Primärschlüssel und der Clustered-Index synonym, also ist der Primärschlüssel geordnet, aber sie sind grundsätzlich zwei verschiedene Dinge. In anderen DBMS können Sie sowohl einen Primärschlüssel als auch einen Clustered-Index definieren, wenn Sie dies tun, wird Ihr Primärschlüssel zu einem eindeutigen Nonclustered-Index mit einem Zeiger zurück auf den Clustered-Index.

Einfach ausgedrückt können Sie sich eine Tabelle mit einer ID-Spalte vorstellen, die der Primärschlüssel ist, und einer weiteren Spalte (A), Ihre B-Tree-Struktur für Ihren Clustered-Index würde in etwa so aussehen:

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 |
            +-----------+   +-----------+   +-----------+

In Wirklichkeit werden die Blattseiten viel größer sein, aber dies ist nur eine Demo. Jede Seite hat auch einen Zeiger auf die nächste Seite und die vorherige Seite, um das Durchqueren des Baums zu erleichtern. Wenn Sie also eine Abfrage wie:

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

Sie scannen einen eindeutigen Index, daher ist es sehr wahrscheinlich, dass es sich um einen sequentiellen Scan handelt. Sehr wahrscheinlich, aber nicht garantiert.

MySQL scannt den Root-Knoten, wenn es eine mögliche Übereinstimmung gibt, geht es weiter zu den Zwischenknoten, wenn die Klausel so etwas wie WHERE ID < 0 war dann würde MySQL wissen, dass es keine Ergebnisse gibt, ohne weiter als bis zum Root-Knoten zu gehen.

Sobald es zum Zwischenknoten weitergeht, kann es erkennen, dass es auf der zweiten Seite (zwischen 4 und 7) beginnen muss, um mit der Suche nach einer ID > 5 zu beginnen . Es scannt also das Blatt sequentiell beginnend mit der zweiten Blattseite, nachdem es bereits LIMIT 1 identifiziert hat Es stoppt, sobald es eine Übereinstimmung findet (in diesem Fall 6) und gibt diese Daten vom Blatt zurück. In einem so einfachen Beispiel erscheint dieses Verhalten zuverlässig und logisch. Ich habe versucht, Ausnahmen zu erzwingen, indem ich einen ID-Wert ausgewählt habe, von dem ich weiß, dass er sich am Ende einer Blattseite befindet, um zu sehen, ob das Blatt in umgekehrter Reihenfolge gescannt wird, konnte dieses Verhalten jedoch noch nicht erzeugen, was jedoch nicht bedeutet es wird nicht passieren, oder dass zukünftige Versionen von MySQL dies in den Szenarien, die ich getestet habe, nicht tun werden.

Kurz gesagt, fügen Sie einfach eine Bestellung hinzu oder verwenden Sie MIN(ID) und fertig. Ich würde nicht zu viel Schlaf verlieren, wenn ich versuchen würde, in die inneren Abläufe des Abfrageoptimierers einzutauchen, um zu sehen, welche Art von Fragmentierung oder Datenbereichen erforderlich wäre, um eine unterschiedliche Reihenfolge des Clustered-Index innerhalb des Abfrageplans zu beobachten.