it-swarm.com.de

Zwei einspaltige Indizes gegen einen zweispaltigen Index in MySQL?

Ich stehe den folgenden Problemen gegenüber und bin mir nicht sicher, was die beste Vorgehensweise ist.

Betrachten Sie die folgende Tabelle (die groß wird):

id PK | giver_id FK | recipient_id FK | Datum

Ich verwende InnoDB und so wie ich es verstehe, erstellt es automatisch Indizes für die beiden Fremdschlüsselspalten. Ich werde jedoch auch viele Abfragen durchführen, bei denen ich eine bestimmte Kombination von folgenden Kriterien erfüllen muss:

SELECT...WHERE giver_id = x AND recipient_id = t.

Jede dieser Kombinationen ist in der Tabelle eindeutig.

Gibt es einen Vorteil, wenn Sie einen zweispaltigen Index über diese Spalten hinzufügen, oder wären die beiden einzelnen Indizes theoretisch ausreichend/gleich?

97
Tom

Wenn Sie zwei einzelne Spaltenindizes 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 einzelner Spaltenindex 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, die eine oder beide Spalten verwenden, schnell, benötigt 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. Weitere Indizes = langsamere Aktualisierungen.

114
Mark Byers

Ein Deckungsindex wie:

ALTER TABLE your_table ADD INDEX (giver_id, recipient_id);

... würde bedeuten, dass der Index verwendet werden könnte, wenn eine Abfrage auf giver_id oder eine Kombination aus giver_id und recipient_id verweist. Beachten Sie, dass die Indexkriterien ganz links basieren - eine Abfrage, die sich nur auf recipient_id Bezieht, kann den Deckungsindex in der von mir angegebenen Anweisung nicht verwenden.

Außerdem kann MySQL nur einen Index pro SELECT verwenden, sodass ein abdeckender Index die beste Möglichkeit darstellt, Ihre Abfragen zu optimieren.

26
OMG Ponies

Wenn einer der Fremdschlüsselindizes bereits sehr selektiv ist, sollte das Datenbankmodul diesen für die von Ihnen angegebene Abfrage verwenden. Die meisten Datenbank-Engines verwenden eine Art Heuristik, um in dieser Situation den optimalen Index zu wählen. 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 diesen Abfragetyp häufig verwenden werden.

Sie sollten auch berücksichtigen, ob Sie das PK-Feld in dieser Tabelle entfernen und den Primärschlüsselindex für die Felder giver_id Und recipient_id Definieren können. Sie sagten, dass die Kombination einzigartig ist, so dass es möglicherweise funktionieren würde (unter vielen anderen Bedingungen, die nur Sie beantworten können). Typischerweise denke ich jedoch, dass die zusätzliche Komplexität, die hinzukommt, den Aufwand nicht wert ist.

4
Mark Wilkins

Eine andere 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 zweispaltige Index erst bei einem bestimmten Schwellenwert für die Datasetgröße oder genau im Gegenteil eine höhere Leistung erzielt. Die Leistungsmetriken für Ihr genaues Szenario können durch nichts ersetzt werden.

1
Andrew