Любой способ добиться полнотекстового поиска в InnoDB

У меня очень простой запрос:

SELECT ... WHERE row LIKE '%some%' OR row LIKE '%search%' OR  row LIKE '%string%'

искать some search string, но, как вы можете видеть, он ищет каждую строку в отдельности, и это также не очень хорошо для производительности.

Есть ли способ воссоздать полнотекстовый поиск, используя LIKE для таблицы InnoDB. Конечно, я знаю, что могу использовать что-то вроде Sphinx для достижения этой цели, но я ищу чистое решение MySQL.

3 ответа

Решение

Используйте полнотекстовую таблицу myisam для индексации ваших таблиц innodb, например:

Создайте свою систему, используя innodb:

create table users (...) engine=innodb;

create table forums (...) engine=innodb;

create table threads
(
forum_id smallint unsigned not null,
thread_id int unsigned not null default 0,
user_id int unsigned not null,
subject varchar(255) not null, -- gonna want to search this... !!
created_date datetime not null,
next_reply_id int unsigned not null default 0,
view_count int unsigned not null default 0,
primary key (forum_id, thread_id) -- composite clustered PK index
)
engine=innodb;

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

create table threads_ft
(
forum_id smallint unsigned not null,
thread_id int unsigned not null default 0,
subject varchar(255) not null,
fulltext (subject), -- fulltext index on subject
primary key (forum_id, thread_id) -- composite non-clustered index 
)
engine=myisam;

Наконец, поиск хранимой процедуры, которую вы вызываете из вашего php/ приложения:

drop procedure if exists ft_search_threads;
delimiter #

create procedure ft_search_threads
(
in p_search varchar(255)
)
begin

select
 t.*,
 f.title as forum_title,
 u.username,
 match(tft.subject) against (p_search in boolean mode) as rank
from
 threads_ft tft
inner join threads t on tft.forum_id = t.forum_id and tft.thread_id = t.thread_id
inner join forums f on t.forum_id = f.forum_id
inner join users u on t.user_id = u.user_id
where
 match(tft.subject) against (p_search in boolean mode) 
order by 
 rank desc
limit 100;

end;

call ft_search_threads('+innodb +clustered +index');

Надеюсь это поможет:)

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

$words=dict($userQuery);
$numwords = sizeof($words);
$innerquery="";
for($i=0;$i<$numwords;$i++) {
    $words[$i] = mysql_real_escape_string($words[$i]);
    if($i>0) $innerquery .= " AND ";
    $innerquery .= "
        (
            field1 LIKE \"%$words[$i]%\" OR
            field2 LIKE \"%$words[$i]%\" OR
            field3 LIKE \"%$words[$i]%\" OR
            field4 LIKE \"%$words[$i]%\"
        )
    ";
}


SELECT fields FROM table WHERE $innerquery AND whatever;

dict - это словарная функция

Полнотекстовый поиск InnoDB (FTS) наконец доступен в выпуске MySQL 5.6.4.

Эти индексы физически представляются в виде целых таблиц InnoDB, на которые действуют ключевые слова SQL, такие как предложение FULLTEXT оператора CREATE INDEX, синтаксис MATCH() ... AGAINST в операторе SELECT и оператор OPTIMIZE TABLE. Из полных текстовых индексов

Другие вопросы по тегам