Ich bin mit folgenden Problemen konfrontiert und bin mir nicht sicher, was die beste Vorgehensweise ist.
Betrachten Sie die folgende Tabelle (die groß wird):
id PK | giver_id FK | Empfänger_ID FK | Datum
Ich verwende InnoDB und nach meinem Verständnis werden automatisch Indizes für die beiden Fremdschlüsselspalten erstellt. Ich werde jedoch auch viele Abfragen durchführen, bei denen ich eine bestimmte Kombination von:
SELECT...WHERE giver_id = x AND recipient_id = t
.
Jede solche Kombination ist in der Tabelle eindeutig.
Gibt es einen Vorteil beim Hinzufügen eines zweispaltigen Index über diese Spalten, oder wären die beiden einzelnen Indizes theoretisch ausreichend / gleich?
Antworten:
Wenn Sie zwei einspaltige Indizes haben, wird in Ihrem Beispiel nur einer davon verwendet.
Wenn Sie einen Index mit zwei Spalten haben, ist die Abfrage möglicherweise schneller (Sie sollten messen). Ein zweispaltiger Index kann auch als einspaltiger Index verwendet werden, jedoch nur für die zuerst aufgeführte Spalte.
Manchmal kann es nützlich sein, einen Index für (A, B) und einen anderen Index für (B) zu haben. Dies macht Abfragen mit einer oder beiden Spalten schnell, verbraucht aber natürlich auch mehr Speicherplatz.
Bei der Auswahl der Indizes müssen Sie auch die Auswirkungen auf das Einfügen, Löschen und Aktualisieren berücksichtigen. Mehr Indizes = langsamere Updates.
quelle
Ein Deckungsindex wie:
... würde bedeuten, dass der Index verwendet werden könnte, wenn auf eine Abfrage verwiesen
giver_id
wird oder eine Kombination ausgiver_id
undrecipient_id
. Beachten Sie, dass die Indexkriterien ganz links basieren - eine Abfrage, auf die nurrecipient_id
verwiesen wird, kann den Deckungsindex in der von mir angegebenen Anweisung nicht verwenden.Darüber hinaus kann MySQL nur einen Index pro SELECT verwenden, sodass ein abdeckender Index das beste Mittel zur Optimierung Ihrer Abfragen ist.
quelle
MySQL can only use one index per SELECT
Dies ist nicht mehr wahr. Es wäre schön, wenn Sie Ihre Antwort so bearbeiten würden, dass sie aktualisiert wird.recipient_id
?INDEX (col1, col2, col3, col4)
wird der Index für Suchvorgänge mit einerWHERE
Klausel wiecol1 = 'A'
odercol1 = 'A' AND col2 = 'B'
oder angewendetcol1 = 'A' AND col2 ='B' AND col3 = 'C' AND col4 = 'D'
, aber dieser bestimmte Index wird für nichts wieWHERE col2 = 'B'
oder verwendet,WHERE col3 = 'C' AND col4 = 'D'
da die Suchfelder in der Indexdefinition nicht am häufigsten belassen werden. Sie müssten zusätzliche Indizes hinzufügen, um diese Felder abzudecken.Wenn einer der Fremdschlüsselindizes bereits sehr selektiv ist, sollte das Datenbankmodul diesen für die von Ihnen angegebene Abfrage verwenden. Die meisten Datenbankmodule verwenden eine Art Heuristik, um in dieser Situation den optimalen Index auswählen zu können. Wenn keiner der Indizes für sich genommen sehr selektiv ist, ist es wahrscheinlich sinnvoll, den auf beiden Schlüsseln basierenden Index hinzuzufügen, da Sie sagen, dass Sie diese Art von Abfrage häufig verwenden werden.
Eine andere Sache zu prüfen ist , ob Sie die PK - Feld in dieser Tabelle beseitigen und den Primärschlüssel Index für die definieren
giver_id
undrecipient_id
Felder. Sie sagten, dass die Kombination einzigartig ist, so dass dies möglicherweise funktionieren würde (unter vielen anderen Bedingungen, die nur Sie beantworten können). Normalerweise denke ich jedoch, dass die zusätzliche Komplexität, die hinzugefügt wird, den Aufwand nicht wert ist.quelle
Eine weitere zu berücksichtigende Sache ist, dass die Leistungsmerkmale beider Ansätze auf der Größe und Kardinalität des Datensatzes basieren. Möglicherweise stellen Sie fest, dass der 2-Spalten-Index erst bei einem bestimmten Schwellenwert für die Datensatzgröße oder genau im Gegenteil leistungsfähiger wird. Nichts kann Leistungsmetriken für Ihr genaues Szenario ersetzen.
quelle