Erhöhen Sie die Geschwindigkeit der MySQL-Abfrage WIE?
Für einen Flughafen-Eingabefeld mit Autovervollständigung gibt es derzeit eine Tabelle mit den Flughafen-Beschreibungen, autocomplete_airport
:
lang | description (with INDEX) | ...
-----+----------------------------------------------------+----
pt | New York - John F Kennedy (JFK), Estados Unidos | ...
pt | Nova Iorque - John F Kennedy (JFK), Estados Unidos | ...
...
Autocompletion funktioniert auf einzelne Wörter. Also, wenn der Benutzer "yor", dann "new york" zeigt sich (im LIMIT). Die Abfrage funktioniert derzeit wie folgt:
SELECT * FROM autocomplete_airport WHERE lang = "pt"
AND (description LIKE "%(yor)%"
OR description LIKE "yor%"
OR description LIKE "% yor%")
ORDER BY description
LIMIT 15
Nun Frage ich mich, wie die Dinge etwas beschleunigen. Eine Idee ist, erstellen Sie die folgenden Datenbank-Struktur, mit Tabellen autocomplete_airport
und autocomplete_airport_word
:
id | lang | description (with INDEX) | ...
-----+------+----------------------------------------------------+----
123 | pt | New York - John F Kennedy (JFK), Estados Unidos | ...
124 | pt | Nova Iorque - John F Kennedy (JFK), Estados Unidos | ...
...
word (with INDEX) | autocomplete_airport_id
------------------+------------------------
New | 123
York | 123
John | 123
F | 123
Kennedy | 123
JFK | 123
...
WÄHLEN Sie dann würde nur noch die Suche am Anfang des strings:
SELECT DISTINCT autocomplete_airport.*
FROM autocomplete_airport
INNER JOIN autocomplete_airport_word
ON autocomplete_airport.id = autocomplete_airport_word.autocomplete_airport_id
WHERE lang = "pt"
AND word LIKE "yor%"
ORDER BY description
LIMIT 15
Ist, dass die neue Struktur der Mühe Wert? Wäre es wirklich die Dinge etwas beschleunigen? Gibt es eine einfachere Möglichkeit?
Update
Ist nur aufgefallen, dass die word-Tabelle hat einen Fehler. Die Folge: die Suche nach "New York" nicht geben würde ohne Ergebnis. Was funktionieren sollte:
term (with INDEX) | autocomplete_airport_id
------------------------------------------------+------------------------
New York - John F Kennedy (JFK), Estados Unidos | 123
York - John F Kennedy (JFK), Estados Unidos | 123
John F Kennedy (JFK), Estados Unidos | 123
F Kennedy (JFK), Estados Unidos | 123
Kennedy (JFK), Estados Unidos | 123
(JFK), Estados Unidos | 123
Estados Unidos | 123
Unidos | 123
JFK | 123
- Machen Sie es wie diese!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als MartinK sagt, wenn Ihre Tabelle hat nur ein paar hundert Zeilen, deine Abfrage sollte ziemlich schnell auch ohne Optimierung - es lohnt sich, was Los ist.
Jedoch, der beste Weg, um search-text-Felder verwenden Sie die Volltext-Indizierung (http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html) - dies ist konzipiert für genau den Fall, dass Sie beschreiben.
Ihre vorgeschlagene Ansatz kann Geschwindigkeit bis Ihre Abfrage. Die wichtige Sache, über das WIE fragt ist, dass der Platzhalter % muss nicht am Anfang des Musters.
LIKE '%foobar'
können Gebrauch machen von einem index.LIKE 'foobar%'
können Gebrauch machen von einem index.Allerdings, wenn Sie nur haben ein paar hundert Flughäfen zu speichern, würde ich denken, zweimal, wenn ein full table scan wirklich weh, dass viel.
Verwenden
EXPLAIN select {rest of query}
um herauszufinden, wie und ob die DB ein.Sehen http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
(Scrollen Sie nach unten, um B-Tree-Index Merkmale, dies ist die Standard-mysql-index-Typ)
LIKE '%foobar'
können Gebrauch machen von einem index. Ja das ist, wasEXPLAIN select {rest of query}
zeigt. Jetzt bin ich am überlegen, ob tun, verwenden Sie die Volltextsuche oder die separate word-Tabelle, die ich ursprünglich vorgeschlagen hatte. Übrigens, es gibt rund 10.000 Einträge prolang
. Sollten einige profiling -...