这是我用来执行论坛搜索的查询。
$sql = "SELECT t.title, t.user_id, t.replies, t.views, t.last_poster_name, t.last_post_time, a.username
FROM fm_topics t
LEFT JOIN fm_replies r
ON t.t_id=r.topic_id
LEFT JOIN account a
ON t.user_id=a.id
WHERE
`title` LIKE '%" . sanitize($search_string) . "%' OR
`content` LIKE '%" . sanitize($search_string) . "%'
GROUP BY t_id LIMIT 0, 10";
以上工作正常。但是,加载需要5秒钟。现在,如果我取出它搜索标题的部分,它加载速度更快(显然)。我的问题是,我该如何改进这个查询?你会如何重写它以获得更好的性能?
答案 0 :(得分:1)
您可以使用MATCH
和AGAINST
等MySql函数。默认情况下,MATCH()
函数针对文本集合执行字符串的自然语言搜索。集合是FULLTEXT索引中包含的一个或多个列的集合。搜索字符串作为AGAINST()
的参数给出。对于表格中的每一行,MATCH()
返回相关性值;也就是说,搜索字符串与MATCH()
列表中指定的列中该行中的文本之间的相似性度量。
Natural Language Full-Text Searches
如果没有在该表上进行索引,则查询不需要优化,而是表。
What is an index in SQL Server?
对于您的方案,即使用通配符进行文本搜索,建议使用Full text indexing
。
答案 1 :(得分:0)
为什么不进行全文搜索和索引呢?这将使搜索速度更快。通过使用LIKE
查询,尤其是前缀为wild-carded的查询,这意味着必须按顺序扫描每一行。
https://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
我会在title,content
上制作两列全文索引:
CREATE FULLTEXT INDEX index_content ON (title,content)
比搜索它:
SELECT ... WHERE MATCH(title, content) AGAINST ("your query")
(可选)使用IN BOOLEAN MODE
- 阅读文档,了解您为什么会使用此修饰符的原因。
如果你真的无法实现全文搜索+索引并且需要保留LIKE
那么你可以考虑在content
上添加常规索引,但是然后利用那个索引你必须删除领先的外卡(你可以保留尾随的); MySQL无法在前导通配符查询中使用索引。