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

Zusammengesetzter FULLTEXT-Index in MySQL

Die Antwort von @Alden Quimby ist soweit richtig, aber die Geschichte hat noch mehr zu bieten, denn MySQL wird es nur versuchen den optimalen Index auszuwählen, und seine Fähigkeit, diese Bestimmung zu treffen, ist aufgrund der Art und Weise, wie Volltextindizes mit dem Optimierer interagieren, begrenzt.

Was tatsächlich passiert, ist Folgendes:

Wenn die angegebene user_id in entweder 0 oder 1 übereinstimmenden Zeilen in der Tabelle vorhanden ist, erkennt der Optimierer dies und wählt user_id als Index für diese Abfrage. Schnelle Ausführung.

Andernfalls wählt der Optimierer den Volltextindex und filtert jede Zeile, die mit dem Volltextindex übereinstimmt, um Zeilen zu eliminieren, die keine user_id enthalten, die mit der WHERE-Klausel übereinstimmt. Nicht ganz so schnell.

Es ist also nicht wirklich der "optimale" Weg. Es ist eher wie Volltext, mit einer netten Optimierung, um die Volltextsuche unter der einen Bedingung zu vermeiden, dass wir wissen, dass wir fast nichts Interessantes in der Tabelle haben.

Der Grund dafür ist, dass ein Volltextindex dem Optimierer keine aussagekräftigen Statistiken zurückgibt. Es heißt nur "Ja, ich denke, diese Abfrage sollte wahrscheinlich nur 1 Zeile prüfen" ... was den Optimierer natürlich sehr freut, sodass der Volltextindex den Zuschlag für die niedrigsten Kosten erhält, es sei denn, der Index mit der Ganzzahl Wert fällt auch vergleichsweise niedrig oder niedriger aus.

Das bedeutet jedoch nicht, dass ich es nicht zuerst auf diese Weise versuchen würde.

Es gibt noch eine weitere Option, die am besten mit Volltextabfragen IN BOOLEAN MODE funktioniert und das heißt, eine weitere Spalte zu erstellen, die Sie mit etwas wie CONCAT('user_id_',user_id) oder etwas Ähnlichem füllen würden, und dann einen zweispaltigen Volltextindex deklarieren.

filter_string VARCHAR(48) # populated with CONCAT('user_id_',user_id);
....
FULLTEXT KEY (message,filter_string)

Geben Sie dann alles in der Abfrage an.

SELECT ...
 WHERE user_id = 500 AND
 MATCH (message,filter_string) AGAINST ('+kittens +puppies +user_id_500' IN BOOLEAN MODE);

Jetzt ist der Volltextindex nur für den Abgleich der Zeilen verantwortlich, in denen Kätzchen, Welpen und "user_id_500" im kombinierten Volltextindex der beiden Spalten erscheinen, aber Sie möchten auch dort den Ganzzahlfilter haben, um sicherzustellen, dass dies der Fall ist Die endgültigen Ergebnisse sind trotz des zufälligen Auftretens von "user_id_500" in der Nachricht eingeschränkt.