Sind Spalten, die keine Indizes sind, zusammen mit dem Index auf der Festplatte sortiert?

8

Sind Spalten, die keine Indizes sind, zusammen mit dem Index in MySQL, MyISAM und InnoDB auf der Festplatte sortiert?

Ein falscher Gedanke, den ich zu schreiben begann:

Ich denke das wahrscheinlich nicht, da sie nicht indiziert sind; Wenn sie sortiert wären, würde dies bedeuten, dass sie Indizes sind.

Dies ist nicht korrekt, da jede Indexspalte nach der Reihenfolge ihres eigenen Inhalts sortiert ist. Ich frage jedoch, ob jede Zeile (oder nur einige Spalten) mit dem entsprechenden Index sortiert werden soll.

Zur Erklärung sage ich: Dies wäre nützlich, um die Auswahl von Zeilenbereichen, die nebeneinander neben ihren Indizes stehen, schneller zu machen. Wenn ich zum Beispiel möchte select * where id >1000 and id<2000(es kann Fehler in der MySQL-Syntax geben, ich weiß es nicht genau), kann die ID-Spalte selbst schnell von der Festplatte gelesen werden, da wahrscheinlich ihre Zellen von 1000 bis 2000 auf der physischen Festplatte zusammen bleiben . Andere Spalteninhalte, die den IDs 1000 bis 2000 entsprechen, können jedoch an verschiedenen Stellen auf der physischen Festplatte geschrieben werden. Wenn sie auch sortiert sind, werden sie schneller gelesen. Ich denke, vielleicht sortiert MySQL diese Spalten auf der physischen Festplatte automatisch, um solche Vorgänge auszuführen.

Sind sie in anderen Datenbanktypen (PostgreSQL usw.) sortiert?

27. Dezember: Aus den beiden Antworten geht hervor, dass in dem Fall, in dem ein Clustered-Index / Primärschlüssel vorhanden ist, die einfachen Zeilen selbst nicht auf der physischen Festplatte sortiert sind (wie ich dachte, dass dies möglich ist), und sogar der Clustered-Index nicht sortiert, wenn es B-Baum ist, habe ich über B-Baum gelesen und sehe, dass seine Knoten, wie ich verstehe, an zufälligen Stellen auf der Festplatte bleiben.

qdinar
quelle

Antworten:

9

In einigen Fällen können sie sortiert sein. Der Sortierindex wird normalerweise als Clustering-Schlüssel bezeichnet . Wenn dies der Fall ist, wird die gesamte Tabelle in einem solchen Index gespeichert (normalerweise in einer Art B-Baum-Struktur).

In dem anderen Fall wird die Tabellenstruktur als Heap bezeichnet , Zeilen werden so wie sie sind gespeichert, wobei "Löcher" in den Datenblöcken gelöscht werden und diese Löcher später mit neuen Zeilen gefüllt werden, sodass nicht einmal die "Einfügereihenfolge" erhalten bleibt.

MyISAM verwendet die Heap- Struktur, wobei jede Zeile durch den Offset (eine Art Array-Index ) in der Datendatei identifiziert wird . Jeder Index enthält dann die indizierten Spalten für jede Zeile, sortiert in der richtigen Reihenfolge und mit der Versatznummer, um die reale Zeile zu lokalisieren. Das bedeutet, dass der Zugriff auf die Zeile über einen beliebigen Index bedeutet, dass die richtigen Knoten im Index (B-Baum) lokalisiert werden und dann die richtigen Versätze aus der Datendatei gelesen werden (zufällige Suche nach einem anderen Teil der Festplatte kann erfolgen) ).

InnoDB verwendet das Clustering nach dem Primärschlüssel (oder wenn keiner definiert ist, wird der erste eindeutige Schlüssel ungleich Null verwendet oder eine interne Autoinkrementierungsspalte hinzugefügt - die Zeilen werden also immer irgendwie sortiert). In einem solchen Fall ist ein Zugriff durch den Primärschlüssel "direkt". Wenn der richtige Wert gefunden wird, haben Sie die gesamte Zeile zur Hand und müssen keinen zweiten Lesevorgang durchführen. Die Sekundärindizes hingegen können keinen Versatz wie in MyISAM speichern (da sich der B-Baum dynamisch neu ausbalanciert, sodass sich der Versatz einer bestimmten Zeile jederzeit ändern kann) und stattdessen die Primärschlüsselwerte der Zeile speichern Zugriff über einen Sekundärschlüssel bedeutet zwei B-Tree-Suchen in InnoDB.

MS SQL Server bietet die Option, den Primärschlüssel (oder einen anderen Index) entweder gruppiert oder nicht gruppiert zu machen, sodass Sie zwischen dem Heap (kein Index ist gruppiert) und der Baumstruktur (ein Index ist gruppiert) wählen können . Alle anderen nicht gruppierten Indizes speichern spezielle Header-Werte (RowID) im Heap-Fall oder die gruppierten Schlüsselwerte der Zeile im Fall des CI.

PostgreSQL verwendet nur Heap- Tabellen, aber Sie können sie bei Bedarf nach einem Index neu anordnen (Sie müssen ihn auslösen, damit die Zeilen nach der Aktion sortiert werden, aber weitere Schreibvorgänge in die Tabelle können diese Reihenfolge wieder aufheben).

TokuDB (eine MySQL / MariaDB-Engine eines Drittanbieters) kann mehrere Clustering-Schlüssel für eine Tabelle verwenden - effektiv werden mehrere Kopien der Tabelle verwaltet, die jeweils unterschiedlich sortiert sind. Es kommt mit einer Strafe schreibt, aber TokuDB Ansprüche zu verwenden some sie nennen Fraktal - Indizes , die diese Strafe ziemlich klein machen sollte.

Wenn Sie diese Funktionalität für einige Abfragen verwenden müssen, können Sie sie "emulieren", indem Sie einen Abdeckungsindex erstellen. Auf diese Weise sind die Spalten, die Ihre Abfrage benötigt, jederzeit in der richtigen Reihenfolge verfügbar. Dies bedeutet jedoch auch, dass eine geordnete Kopie von (Teilen von) beibehalten wird ) die Tabelle in Ihren Indizes.

jkavalik
quelle
5

Die kurze und einfache Antwort für Datenbanken im Allgemeinen lautet: Nein, die physische Reihenfolge der Zeilen in einer Tabelle ist im Allgemeinen nicht dieselbe wie in einem Index für diese Tabelle.

Im Allgemeinen (ich sage im Allgemeinen, weil es spezielle Fälle gibt, in denen dies nicht zutrifft) sind die Tabelle und der Index zwei verschiedene physische Strukturen auf der Festplatte. Herkömmliche RDBMs Speichern von Daten so , dass die Werte aus einer Tabelle Zeile (nicht Spalte ) angeordnet sind , nebeneinander auf der Festplatte; Die Zeilen selbst werden nicht in einer bestimmten Reihenfolge gespeichert. Indexeinträge hingegen werden der Reihe nach gespeichert; Ein typischer B-Tree-Index enthält sortierte Werte von indizierten Spalten (aber keine anderen Spalten!) und eine Art Zeiger auf die Position der gesamten Zeile in der Tabelle, die, wie bereits erwähnt, eine separate physische Struktur auf der Festplatte darstellt.

Davon abgesehen gibt es Sonderfälle. In der InnoDB von MySQL werden beispielsweise tatsächliche Datenzeilen in einer indexähnlichen Struktur gespeichert. Der Index, nach dem Zeilen in eine solche "Indextabelle" eingefügt werden, ist normalerweise der Primärschlüssel der Tabelle. und ein solcher Index wird als Clustered-Index bezeichnet . Natürlich kann eine InnoDB-Tabelle andere Indizes haben, und die Reihenfolge der Zeilen (dh Zeilenspalten, die im jeweiligen Index enthalten sind) in diesen Indizes hat nichts mit der Reihenfolge der Zeilen in der Tabelle selbst zu tun.

zgguy
quelle