2011-08-17 173 views
2

我正在构建一个论坛,并且正在寻找合适的方法来构建一个搜索功能,通过他们的姓名或职位名称来查找用户。我得到的是这样的:MySQL:使用LIKE或FULLTEXT优化搜索

SELECT users.id, users.user_name, users.user_picture 
FROM users, subject1, subject2 
WHERE users.id = subject1.user_id 
AND users.id = subject2.user_id 
AND (users.user_name LIKE '%{$keywords}%' 
OR subject1.title1 LIKE '%{$keywords}%' 
OR subject2.title2 LIKE '%{$keywords}%') 
ORDER BY users.user_name ASC 
LIMIT 10 
OFFSET {$offset} 

LIMIT和OFFSET是分页。我的问题是,当行数达到相当数量时,是否会通过多个表进行LIKE搜索,从而大大降低性能?

我有几个备选方案: 一个,也许我可以重写该查询,使LIKE搜索在只返回索引user_ids的子查询中完成。然后,我会根据该信息找到其余的用户信息。这会提高性能吗?

第二,我想我可以在LIKE {$keyword}%的第一个通配符之前出现$keyword字符串。这样,我可以索引user_name, title1, and title2列。但是,因为我会在这里交易速度的准确性,所以这会带来多大的性能差异?为索引这些列而牺牲这么高的精度是否值得?

三,也许我可以给用户3个搜索字段选择,并且每个搜索只能通过一个表。这会提高性能吗?

最后,我应该考虑使用FULLTEXT搜索而不是LIKE?两者之间的性能差异是什么?另外,我的表使用的是InnoDB存储引擎,除非切换到MyISAM,否则我无法使用FULLTEXT索引。切换到MyISAM会有什么重大区别吗?

分页是我担心的另一个性能问题,因为为了执行分页,我需要查找查询返回的结果总数。目前,我基本上只是在做TWICE的查询,因为第一次使用时只用于COUNT的结果。

回答

3

,我们在您查询两件事情,以防止MySQL的使用指标,首先你的模式开始通配符%,MySQL不能使用索引来搜索与通配符启动模式,其次,你在你的WHEREOR子句,您需要使用UNION来重写您的查询以避免使用OR,这也会阻止MySql使用索引。在不使用索引的情况下,MySql每次都需要执行全表扫描,并且所需的时间将随着表中行数的增加而线性增加,是的,正如您所说的那样“当行数会大大减慢性能时达到一个很大的数额“,所以我会说你唯一真正的可扩展选项是使用FULLTEXT搜索。

0

切换到MyISAM应该可以毫无用处地工作。唯一的缺点是,MyISAM会在插入/更新时锁定整个表格,这可能会导致表格插入速度比选择更慢。基本上,我认为在不需要外键的情况下使用MyISAM,并且该表的选择比插入选择多得多,并且在表具有比选择更多的插入/更新时使用InnoDB(例如,对于统计表) 。

在你的情况下,我猜想切换到MyISAM是更好的选择,因为全文索引功能更强大,速度更快。

它还提供了使用某些查询修饰词的可能性,如排除词(“cat -dog”)或类似词。但请记住,不可能像LIKE搜索一样查找以短语结尾的单词(“*bar”)。 “foo*”将工作。

+0

我期待有大量的写入到我的表中,但不超过SELECT的数量。你会不会推荐我在这种情况下切换到MyISAM全文索引? – recount88 2011-08-17 13:25:33