Я пытаюсь создать маленький поиск моего сайта. Я попытался использовать полнотекстовый поиск по индексу, но я никогда не мог заставлять его работать. Вот то, что я придумал:
if(isset($_GET['search'])) {
$search = str_replace('-', ' ', $_GET['search']);
$result = array();
$titles = mysql_query("SELECT title FROM Entries WHERE title LIKE '%$search%'");
while($row = mysql_fetch_assoc($titles)) {
$result[] = $row['title'];
}
$tags = mysql_query("SELECT title FROM Entries WHERE tags LIKE '%$search%'");
while($row = mysql_fetch_assoc($tags)) {
$result[] = $row['title'];
}
$text = mysql_query("SELECT title FROM Entries WHERE entry LIKE '%$search%'");
while($row = mysql_fetch_assoc($text)) {
$result[] = $row['title'];
}
$result = array_unique($result);
}
Так в основном это перерывает все заголовки, основной текст и теги всех записей в DB. Это работает прилично хорошо, но я просто задаюсь вопросом, насколько эффективный это было бы? Это только было бы для маленького блога, также. Так или иначе я просто задаюсь вопросом, могло ли это больше делаться эффективным.
Невозможно сделать запросы LIKE '% pattern%'
эффективными. Как только вы получаете нетривиальный объем данных, использование этих запросов с подстановочными знаками выполняется в сотни или тысячи раз медленнее, чем использование решения для полнотекстового индексирования.
Вам следует взглянуть на презентацию, которую я сделал для MySQL University: http://www.slideshare.net/billkarwin/practical-full-text-search-with-my-sql
Вот как заставить его работать:
Сначала убедитесь, что ваша таблица использует MyISAM двигатель хранения. Индексы MySQL FULLTEXT поддерживают только таблицы MyISAM. ( редактировать 01.11.2012: MySQL 5.6 представляет тип индекса FULLTEXT для таблиц InnoDB.)
ALTER TABLE Entries ENGINE = MyISAM;
Создать полнотекстовый индекс.
CREATE FULLTEXT INDEX searchindex ON Записи (заголовок, теги, запись);
Ищите!
$ search = mysql_real_escape_string ($ search);
$ title = mysql_query ("ВЫБРАТЬ заголовок ИЗ записей
ГДЕ МАТЧ (заголовок, теги, запись) ПРОТИВ ('$ search') ");
while ($ row = mysql_fetch_assoc ($ title)) {
$ result [] = $ row ['название'];
}
Обратите внимание, что столбцы, которые вы называете в предложении MATCH
, должны быть теми же столбцами в том же порядке, что и те, которые вы объявили в определении полнотекстового индекса. Иначе не получится.
Я пробовал использовать полнотекстовый поиск по индексу, но так и не смог заставить его работать ... Мне просто интересно, можно ли сделать это более эффективным.
Это как если бы я сказал: «Я не мог понять, как пользоваться этой бензопилой, поэтому решил срубить это красное дерево перочинным ножом. Как я могу заставить это работать так же хорошо, как бензопилу?»
] По поводу вашего комментария о поиске слов, которые соответствуют более чем 50% строк.
В руководстве MySQL сказано это :
Пользователи, которым необходимо обойти ограничение в 50%, могут использовать логический режим поиска; см. Раздел 11.8.2, «Логический полнотекстовый поиск» .
И this :
50% порог для естественного языка поиск определяется выбрана конкретная схема взвешивания. К отключите его, найдите следующее строка в хранилище / myisam / ftdefs.h:
#define GWS_IN_USE GWS_PROB
Измените эту строку на эту:
#define GWS_IN_USE GWS_FREQ
Затем перекомпилируйте MySQL. Нет необходимости для восстановления индексов в этом случае.
Кроме того, вы можете искать стоп-слов . Это слова, которые игнорируются при полнотекстовом поиске, потому что они слишком распространены. Такие слова, как «the» и так далее. См. http://dev.mysql.com/doc/refman/5.1/en/fulltext-stopwords.html
Использование LIKE
не является НЕ полнотекстовым.
Вам необходимо использовать ... WHERE MATCH (столбец) AGAINST ('запрос')
, чтобы получить доступ к полнотекстовому поиску.
Полнотекстовый поиск MySQL работает - я бы изучил его и отладил, а не пытался это сделать. Выполнение трех отдельных запросов MySQL не будет столь же эффективным.
Если вы хотите добиться максимальной эффективности, вы можете разделить операторы LIKE
в одном запросе с помощью OR
между ними.