2009-08-09 13 views
29

Das ist eine Frage, die ich für immer hatte.MySQL Indizes und Bestellung

Soweit ich weiß, ist die Reihenfolge der Indizes wichtig. Also ein Index wie [first_name, last_name] ist nicht das gleiche wie [last_name, first_name], richtig?

Wenn ich nur den ersten Index definieren, bedeutet es, dass es nur für

SELECT * FROM table WHERE first_name="john" AND last_name="doe"; 

und

SELECT * FROM table WHERE last_name="doe" AND first_name="john"; 

Da ich ein ORM verwenden, verwendet wird für nicht

ich keine Ahnung, in In welcher Reihenfolge werden diese Spalten aufgerufen? Bedeutet das, dass ich Indizes für alle Permutationen hinzufügen muss? Das ist machbar, wenn ich einen 2-Spalten-Index habe, aber was passiert, wenn mein Index auf 3 oder 4 Spalten steht?

Antwort

44

Die Indexreihenfolge ist wichtig, wenn Ihre Abfragebedingungen nur für PART des Index gelten. Bedenken Sie:

  1. SELECT * FROM table WHERE first_name="john" AND last_name="doe"

  2. SELECT * FROM table WHERE first_name="john"

  3. SELECT * FROM table WHERE last_name="doe"

Wenn Ihr Index (first_name, last_name) abfragt 1 und 2 wird es verwenden, Abfrage # 3 gewonnen t. Wenn Ihr Index ist (last_name, first_name) Abfragen 1 und 3 wird es verwenden, Abfrage # 2 wird nicht. Das Ändern der Konditionsreihenfolge innerhalb der WHERE-Klausel hat in beiden Fällen keine Auswirkung.

Einzelheiten sind here

aktualisieren:
Fall In dem oben nicht klar ist - MySQL einen Index nur verwenden, wenn die Spalten in Abfragebedingungen einen linken Präfix des Index bilden. Die zweite Abfrage Nr. 2 kann den Index (last_name, first_name) nicht verwenden, da er nur auf first_name basiert und first_name NICHT das äußerst linke Präfix des Indexes (last_name,) ist.

Die Reihenfolge der Bedingungen in der Abfrage spielt keine Rolle; Abfrage Nr. 1 oben kann (last_name, first_name) Index einfach gut verwenden, da seine Bedingungen first_name und last_name sind und zusammen bilden sie einen ganz linken Präfix von (last_name, first_name) Index.

+0

Also ich denke SELECT * FROM Tabelle WHERE last_name = "doe" UND first_name = "John" wird nicht? Wenn dies der Fall ist, dann, da alle Abfrage Gebäude von meinem ORM versteckt ist, muss ich wahrscheinlich die 2 Indizes definieren ... was wirklich saugt, weil ich einen Index auf 3 Spalten zu definieren haben ... –

+1

Nein, du hast es falsch verstanden. WHERE 'last_name' =" doe "AND' first_name' = "john" -Abfrage würde entweder ('first_name',' last_name') oder ('last_name',' first_name') nur gut verwenden. – ChssPly76

+0

Eine Frage: Für eine Abfrage mit 2 AND-Bedingungen ist es wichtig, Geschwindigkeit, es ist der Index "umgekehrt" im Vergleich zu den Bedingungen in der Abfrage, oder es hängt von der Kardinalität dieser Spalten? – Mihai

5

ChssPly76 ist korrekt, dass die Reihenfolge der booleschen Ausdrücke nicht mit der Reihenfolge der Spalten im Index übereinstimmen muss. Boolesche Operatoren sind commutative, und der MySQL-Optimierer ist schlau genug, um zu wissen, wie man den Ausdruck in den meisten Fällen an den Index anpasst.

Ich möchte auch hinzufügen, dass Sie lernen sollten, wie die EXPLAIN-Funktion von MySQL zu verwenden, damit Sie selbst sehen können, welche Indizes das Optimierungsprogramm für eine bestimmte Abfrage auswählen wird.

+2

+1 für erklären. – Petrogad

+0

MySQL Workbench zeigt eine grafische Darstellung der EXPLAIN-Informationen unter "Ausführungsplan". –

2

Warum nicht die Antwort ein wenig erweitern, um alles kristallklar auf einmal zu machen.

Wenn die Tabelle über einen mehrspaltigen Index verfügt, kann ein beliebiges linkes Präfix des Index vom Optimierungsprogramm zum Suchen von Zeilen verwendet werden. Wenn Sie beispielsweise einen dreispaltigen Index für (col1, col2, col3) haben, haben Sie die Suchfunktionen unter (col1), (col1, col2) und (col1, col2, col3) indiziert.

MySQL kann keinen Index verwenden, wenn die Spalten kein linkes Präfix des Indexes bilden. Nehmen wir an, dass Sie die SELECT-Anweisungen haben hier gezeigt:

SELECT * FROM tbl_name WHERE col1=val1; 
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2; 

SELECT * FROM tbl_name WHERE col2=val2; 
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3; 

Wenn ein Index auf (col1, col2, col3) vorhanden ist, werden nur die ersten beiden Abfragen den Index verwenden. Bei der dritten und vierten Abfrage handelt es sich um indizierte Spalten, aber (col2) und (col2, col3) sind keine Präfixe ganz links von (col1, col2, col3). - MySQL dev