Увеличить скорость запроса MySQL LIKE? - PullRequest
4 голосов
/ 15 марта 2012

Для поля ввода в аэропорту с автозаполнением в настоящее время существует одна таблица с описаниями аэропорта, autocomplete_airport:

lang | description (with INDEX)                           | ...
-----+----------------------------------------------------+----
pt   | New York - John F Kennedy (JFK), Estados Unidos    | ...
pt   | Nova Iorque - John F Kennedy (JFK), Estados Unidos | ...
...

Автозаполнение работает с отдельными словами.Поэтому, когда пользователь вводит «yor», тогда появляется «new york» (если в LIMIT).В настоящее время запрос работает следующим образом:

SELECT * FROM autocomplete_airport WHERE lang = "pt"
AND (description LIKE "%(yor)%"
     OR description LIKE "yor%"
     OR description LIKE "% yor%")
ORDER BY description
LIMIT 15

Теперь мне интересно, как ускорить процесс.Одна из идей состоит в том, чтобы создать следующую структуру базы данных с таблицами autocomplete_airport и 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
...

Тогда SELECT потребуется выполнять поиск только в начале строк:

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

Стоит ли эта новая структура проблем?Это действительно ускорит вещи?Есть ли более простой способ?

Обновление

Только что заметил, что таблица слов имеет недостаток.Следствие: поиск «Нью-Йорк» не даст никакого результата.Что должно работать:

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

Ответы [ 2 ]

5 голосов
/ 15 марта 2012

Как говорит MartinK, если в вашей таблице всего несколько сотен строк, ваш запрос должен быть довольно быстрым даже без оптимизации - стоит проверить, что происходит.

Однако лучший способ поиска по текстовым полям - использовать полнотекстовое индексирование (http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html) - это разработано именно для того случая, который вы описываете.

4 голосов
/ 15 марта 2012

Ваш предложенный подход может ускорить ваш запрос. Важным моментом в запросах LIKE является то, что подстановочный знак% не должен быть в начале шаблона.

LIKE '%foobar' не может использовать индекс. LIKE 'foobar%' может использовать индекс.

Однако, если у вас просто есть несколько сотен аэропортов для хранения, я бы подумал дважды, если полное сканирование таблицы действительно так больно.

Используйте EXPLAIN select {rest of query}, чтобы узнать, как и использует ли БД.

См. http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html (Прокрутите вниз до Характеристики индекса B-Tree , это тип индекса mysql по умолчанию)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...