Эффективность поиска MySQL / PHP

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

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); } 

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

LIKE '%pattern%' сделать запросы LIKE '%pattern%' эффективными. Как только вы получите нетривиальное количество данных, использование этих подстановочных запросов выполняется в сотни или тысячи раз медленнее, чем использование полнотекстового индексационного решения.

Вы должны посмотреть презентацию, которую я сделал для Университета MySQL: http://www.slideshare.net/billkarwin/practical-full-text-search-with-my-sql

Вот как заставить его работать:

  1. Сначала убедитесь, что в вашей таблице используется механизм хранения MyISAM. Индексы MySQL FULLTEXT поддерживают только таблицы MyISAM. ( edit 11/1/2012: MySQL 5.6 вводит индексный тип FULLTEXT для таблиц InnoDB.)

     ALTER TABLE Entries ENGINE=MyISAM; 
  2. Создайте полный текст.

     CREATE FULLTEXT INDEX searchindex ON Entries(title, tags, entry); 
  3. Найдите его!

     $search = mysql_real_escape_string($search); $titles = mysql_query("SELECT title FROM Entries WHERE MATCH(title, tags, entry) AGAINST('$search')"); while($row = mysql_fetch_assoc($titles)) { $result[] = $row['title']; } 

    Обратите внимание, что столбцы, которые вы MATCH предложении MATCH , должны быть одинаковыми столбцами в том же порядке, что и те, которые вы указали в определении полнотекстового индекса. Иначе это не сработает.


Я пытался использовать полнотекстовый поиск по индексу, но я никогда не смог заставить его работать … Мне просто интересно, можно ли сделать это более эффективным.

Это точно так же, как сказать: «Я не мог понять, как использовать эту бензопилу, поэтому я решил срубить это дерево красного дерева с помощью карманного ножа. Как я могу сделать эту работу, а также бензопилу?»


Что касается вашего комментария о поиске слов, которые соответствуют более 50% строк.

В руководстве MySQL сказано следующее :

Пользователи, которым необходимо обходить ограничение 50%, могут использовать режим логического поиска; см. Раздел 11.8.2, «Логические полнотекстовые поиски» .

И это :

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(column) AGAINST('the query') , чтобы получить доступ к полнотекстовому поиску.

MySQL Полнотекстовый поиск работает – я бы посмотрел на него и отлаживал его, а не пытался это сделать. Выполнение 3 отдельных запросов MySQL не будет таким эффективным.

Если вы хотите попытаться сделать так эффективно, вы можете разделить операторы LIKE в одном запросе с OR между ними.