Das erste, was Sie wissen müssen, ist, dass Indizes eine Möglichkeit sind, das Scannen der vollständigen Tabelle zu vermeiden, um das gewünschte Ergebnis zu erhalten.
Es gibt verschiedene Arten von Indizes, die in der Speicherebene implementiert sind. Daher gibt es keinen Standard zwischen ihnen und sie hängen auch von der von Ihnen verwendeten Speicher-Engine ab.
InnoDB und der B + Tree Index
Für InnoDB ist der häufigste Indextyp der B + Tree-basierte Index, der die Elemente in einer sortierten Reihenfolge speichert. Außerdem müssen Sie nicht auf die reale Tabelle zugreifen, um die indizierten Werte abzurufen, wodurch Ihre Abfrage schneller zurückkehrt.
Das "Problem" bei diesem Indextyp besteht darin, dass Sie nach dem Wert ganz links fragen müssen, um den Index zu verwenden. Wenn Ihr Index also zwei Spalten enthält, z. B. Nachname und Vorname, ist die Reihenfolge, in der Sie diese Felder abfragen , von großer Bedeutung .
Also, gegeben die folgende Tabelle:
CREATE TABLE person (
last_name VARCHAR(50) NOT NULL,
first_name VARCHAR(50) NOT NULL,
INDEX (last_name, first_name)
);
Diese Abfrage würde den Index nutzen:
SELECT last_name, first_name FROM person
WHERE last_name = "John" AND first_name LIKE "J%"
Aber der folgende würde nicht
SELECT last_name, first_name FROM person WHERE first_name = "Constantine"
Weil Sie first_name
zuerst die Spalte abfragen und es nicht die Spalte ganz links im Index ist.
Dieses letzte Beispiel ist noch schlimmer:
SELECT last_name, first_name FROM person WHERE first_name LIKE "%Constantine"
Denn jetzt vergleichen Sie den rechten Teil des Feldes ganz rechts im Index.
Der Hash-Index
Dies ist ein anderer Indextyp, den leider nur das Speicher-Backend unterstützt. Es ist blitzschnell , aber nur dann sinnvoll für die vollständige Lookups, was bedeutet , dass Sie es nicht für Operationen verwenden möchten >
, <
oder LIKE
.
Da es nur für das Speicher-Backend funktioniert, werden Sie es wahrscheinlich nicht sehr oft verwenden. Der Hauptfall, an den ich jetzt denken kann, ist der, bei dem Sie eine temporäre Tabelle im Speicher mit einer Reihe von Ergebnissen aus einer anderen Auswahl erstellen und viele andere Auswahlen in dieser temporären Tabelle mithilfe von Hash-Indizes durchführen.
Wenn Sie ein großes VARCHAR
Feld haben, können Sie die Verwendung eines Hash-Index bei Verwendung eines B-Baums "emulieren", indem Sie eine weitere Spalte erstellen und einen Hash mit dem großen Wert darauf speichern. Angenommen, Sie speichern eine URL in einem Feld und die Werte sind ziemlich groß. Sie können auch ein Ganzzahlfeld mit dem Namen erstellen url_hash
und eine Hash-Funktion wie CRC32
oder eine andere Hash-Funktion verwenden, um die URL beim Einfügen zu hashen. Wenn Sie diesen Wert abfragen müssen, können Sie Folgendes tun:
SELECT url FROM url_table WHERE url_hash=CRC32("http://gnu.org");
Das Problem mit dem obigen Beispiel ist, dass, da die CRC32
Funktion einen ziemlich kleinen Hash generiert, viele Kollisionen in den Hash-Werten auftreten. Wenn Sie genaue Werte benötigen, können Sie dieses Problem wie folgt beheben:
SELECT url FROM url_table
WHERE url_hash=CRC32("http://gnu.org") AND url="http://gnu.org";
Es lohnt sich immer noch, Dinge zu hashen, auch wenn die Kollisionszahl hoch ist, da Sie nur den zweiten Vergleich (den ersten) mit den wiederholten Hashes durchführen.
Leider müssen Sie mit dieser Technik immer noch die Tabelle treffen, um das url
Feld zu vergleichen .
Einpacken
Einige Fakten, die Sie jedes Mal berücksichtigen sollten, wenn Sie über Optimierung sprechen möchten:
Der Ganzzahlvergleich ist viel schneller als der Zeichenfolgenvergleich. Dies kann anhand des Beispiels zur Emulation des Hash-Index in veranschaulicht werden InnoDB
.
Das Hinzufügen zusätzlicher Schritte in einem Prozess macht ihn möglicherweise schneller und nicht langsamer. Dies kann durch die Tatsache veranschaulicht werden, dass Sie a optimieren können, indem Sie SELECT
es in zwei Schritte aufteilen, den ersten Wert in einer neu erstellten In-Memory-Tabelle speichern und dann die schwereren Abfragen für diese zweite Tabelle ausführen.
MySQL hat auch andere Indizes, aber ich denke, der B + Tree ist der am häufigsten verwendete und der Hash ist eine gute Sache zu wissen, aber Sie können die anderen in der MySQL-Dokumentation finden .
Ich empfehle Ihnen dringend, das Buch "High Performance MySQL" zu lesen. Die obige Antwort basierte definitiv auf dem Kapitel über Indizes.