Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Volltext- und zusammengesetzte Indizes und wie sie sich auf die Abfrage auswirken

Wenn ich Ihre Frage verstehe, wissen Sie, dass der MATCH AGAINST Ihren FULLTEXT-Index verwendet, und Sie fragen sich, wie MySQL den Rest der WHERE-Klausel anwendet (dh führt es einen Tablescan oder eine indizierte Suche durch).

Folgendes nehme ich zu Ihrer Tabelle an:Sie hat einen PRIMARY KEY in einer ID-Spalte und den FULLTEXT-Index.

Zunächst einmal wird MySQL niemals Verwenden Sie den FULLTEXT-Index für die WHERE-Klausel der Stadt/des Staates. Wieso den? Denn FULLTEXT-Indizes gelten nur bei MATCH AGAINST. Siehe hier im Absatz nach den ersten Aufzählungszeichen (nicht die Aufzählungszeichen des Inhaltsverzeichnisses).

BEARBEITEN: Vorausgesetzt, Ihre Tabelle hat nicht nur etwa 10 Zeilen, wendet MySQL in Ihrem Fall den FULLTEXT-Index für Ihre ÜBEREINSTIMMUNG AN und führt dann einen Tablescan für diese Ergebnisse durch, um die Stadt/das Bundesland WO anzuwenden.

Was also, wenn Sie Stadt und Staat einen BTREE-Index hinzufügen?

CREATE INDEX city__state ON table (city(10),state(2)) USING BTREE;

Nun, MySQL kann nur einen verwenden Index für diese Abfrage, da es sich um eine einfache Auswahl handelt. Es wird entweder Verwenden Sie den VOLLTEXT oder der BTREE. Beachten Sie, dass ich mit einem Index eine Indexdefinition meine, nicht eine Spalte in einem mehrteiligen Index. Allerdings stellt sich dann die Frage, was man macht es verwenden?

Das hängt von der Tabellenanalyse ab. MySQL wird versuchen, zu schätzen (basierend auf den Tabellenstatistiken der letzten OPTIMIZE TABLE), welcher Index die meisten Datensätze bereinigt. Wenn die Stadt/der Bundesstaat WHERE Sie auf 10 Datensätze herunterbringt, während Sie der MATCH AGAINST nur auf 100 herunterbringt, dann verwendet MySQL zuerst den city_state-Index für die Stadt/den Staat WO und dann einen Tablescan für das MATCH GEGEN machen.

Auf der anderen Seite, wenn MATCH_AGAINST Sie auf 10 Datensätze herunterbringt, während die Stadt/Staat WHERE Sie nur auf 1000 herunterbringt, dann wendet MySQL zuerst den FULLTEXT-Index an und führt einen Tablescan für Stadt und Staat durch.

Das Endergebnis ist die Kardinalität Ihres Indexes. Wie einzigartig sind die Werte, die in Ihren Index eingehen? Wenn für jeden Datensatz in Ihrer Tabelle die Stadt Oakland festgelegt ist, ist dies kein sehr eindeutiger Schlüssel und daher city ='Oakland' reduziert die Anzahl der Datensätze für Sie nicht wirklich. In diesem Fall sagen wir, dass Ihr city__state-Index eine niedrige Kardinalität hat .

Wenn also 90 % der Wörter in Ihrem VOLLTEXT-Index "John" sind, dann hilft Ihnen das aus genau denselben Gründen auch nicht wirklich weiter.

Wenn Sie sich den Platz und den UPDATE/DELETE/INSERT-Overhead leisten können, würde ich empfehlen, den BTREE-Index hinzuzufügen und MySQL entscheiden zu lassen, welchen Index er verwenden möchte. Meiner Erfahrung nach macht er es normalerweise sehr gut, den richtigen auszuwählen.

Ich hoffe, das beantwortet Ihre Frage.

BEARBEITEN: Stellen Sie nebenbei sicher, dass Sie die richtige Größe für Ihren BTREE-Index auswählen (in meinem Beispiel habe ich die ersten 10 Zeichen in der Stadt ausgewählt). Dies hat offensichtlich einen großen Einfluss auf die Kardinalität. Wenn Sie Stadt(1) ausgewählt haben, erhalten Sie offensichtlich eine niedrigere Kardinalität als bei Stadt(10).

EDIT2: Den Abfrageplan (Schätzung) von MySQL, für den der Index die meisten Datensätze bereinigt, sehen Sie in EXPLAIN.