MySQL полнотекстовый поиск, но с использованием LIKE - PullRequest
1 голос
/ 07 апреля 2011

В последнее время я выполняю поиск строк из таблицы, содержащей около 50 тыс. Строк, я бы сказал, довольно большой, но не такой большой. Я делал несколько вложенных запросов для «поиска по результатам». Я использовал оператор LIKE, чтобы получить соответствие искомого ключевого слова.

Я наткнулся на полнотекстовый поиск MySQL, который я попробовал, поэтому я добавил полнотекстовый индекс в свой столбец str. Мне известно, что полнотекстовый поиск не работает с виртуально созданными таблицами или даже с Views, поэтому запросы с вложенными выборками не подойдут. Я упоминал, что делал вложенные запросы, пример:

SELECT s2.id, s2.str 
FROM 
    (
    SELECT s1.id, s1.str 
    FROM 
        (
         SELECT id, str 
         FROM strings 
         WHERE str LIKE '%term%'
         ) AS s1 
    WHERE s1.str LIKE '%another_term%'
    ) AS s2 
WHERE s2.str LIKE '%a_much_deeper_term%';

На самом деле это еще не применимо ни к одному коду, я просто делал несколько тестов. Кроме того, поиск таких строк может быть легко осуществлен с помощью Sphinx (с точки зрения производительности), но давайте рассмотрим Sphinx, который недоступен, и я хочу знать, как это будет работать в чистом SQL-запросе. Выполнение этого запроса для таблицы без добавления полнотекстового кода занимает около 2.97 secs. (зависит от условия поиска). Однако выполнение этого запроса для таблицы с полнотекстовым добавлением в столбец str завершилось примерно за 104 мс, что быстро (я думаю?).

Мой вопрос прост: допустимо ли использовать LIKE или целесообразно использовать его вообще в таблице с полным текстом, добавленным, когда обычно мы используем MATCH и ПРОТИВ заявлений?

Спасибо!

1 Ответ

1 голос
/ 07 апреля 2011

В этом случае вам необязательно нужны подвыборы.Вы можете использовать siply:

SELECT id, str
FROM item_strings
WHERE str LIKE '%term%'
   AND str LIKE '%another_term%'
   AND str LIKE '%a_much_deeper_term%'

... но также возникает хороший вопрос: порядок, в котором вы исключаете строки.Я предполагаю, что MySQL достаточно умен, чтобы предположить, что самый длинный термин будет самым строгим, поэтому, начиная с a_much_deeper_term, он удалит большинство записей, а затем выполнит дополнительное сравнение только в нескольких строках.- В противоположность этому, если вы начнете с term, вы, вероятно, получите множество возможных записей, тогда вам придется сравнивать их со списком терминов.

Интересно то, что вы можете форсировать ордерв котором сравнение производится с использованием вашего исходного примера subselect .Это дает возможность принять решение, какой термин является наиболее ограничивающим, основываясь на большем числе хана, только на длине, но, например:

  • отношение согласных к гласным
  • самая длинная цепьсогласных слова
  • наиболее часто используемых гласных в слове

... и т. д.Вы также можете применить эвристику в зависимости от типа текстовой информации, с которой вы работаете.

Редактировать:

Это всего лишь догадка, но этоможет быть возможно применить LIKE к words в самом полнотекстовом индексе.Затем сопоставьте строки с индексом, как если бы вы указали полные слова.

Я не уверен, что это на самом деле сделано, но это было бы разумным решением для пользователей MySQL.Также обратите внимание, что эту теорию можно использовать только в том случае, если все возможные вхождения фактически находятся в полнотекстовом поиске.Для этого вам необходимо:

  • Ваш шаблон поиска должен быть по крайней мере размером с максимальную длину слова.(Если вы ищете, например, %id%, то он также может быть частью трехбуквенного слова, которое по умолчанию исключено из индекса FULLTEXT).
  • Ваш шаблон поиска не должен быть подстрокой любого из перечисленныхисключаемое слово, например: и, и т. д.
  • Ваш шаблон не должен содержать никаких специальных символов.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...