开发者

Any way to achieve fulltext-like search on InnoDB

I have a very simple query:

SELECT ... WHERE row LIKE '%some%' OR row LIKE '%search%' O开发者_JS百科R  row LIKE '%string%'

to search for some search string, but as you can see, it searches for each string individually and it's also not good for performance.

Is there a way to recreate a fulltext-like search using LIKE on an InnoDB table. Of course, I know I can use something like Sphinx to achieve this but I'm looking for a pure MySQL solution.


use a myisam fulltext table to index back into your innodb tables for example:

Build your system using 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;

Now the fulltext search table which we will use just to index back into our innodb tables. You can maintain rows in this table either by using a trigger or nightly batch updates etc.

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;

Finally the search stored procedure which you call from your php/application:

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

Hope this helps :)


Using PHP to construct the query. This is an horrible hack. Once seen, it can't be unseen...

$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 is a dictionary function


InnoDB full-text search (FTS) is finally available in MySQL 5.6.4 release.

These indexes are physically represented as entire InnoDB tables, which are acted upon by SQL keywords such as the FULLTEXT clause of the CREATE INDEX statement, the MATCH() ... AGAINST syntax in a SELECT statement, and the OPTIMIZE TABLE statement. From FULLTEXT Indexes

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜