简体   繁体   English

使用WHERE之类的慢MySQL查询

[英]Slow MySQL query using WHERE like

This is the query I'm using to perform a forum search. 这是我用来执行论坛搜索的查询。

$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";

The above works fine. 以上工作正常。 However, it takes like 5+ seconds to load. 但是,加载大约需要5秒钟以上的时间。 Now, if I take out the part where it searches for the title too, it loads way faster (obviously). 现在,如果我也从中删除搜索标题的部分,则加载速度会更快(显然)。 My question is, how can I improve this query? 我的问题是,如何改善此查询? how would you rewrite it for better performance? 您将如何重写它以获得更好的性能?

You can use MySql functions like MATCH and AGAINST . 您可以使用MySql函数,例如MATCHAGAINST By default, the MATCH() function performs a natural language search for a string against a text collection. 默认情况下, MATCH()函数针对文本集合对字符串执行自然语言搜索。 A collection is a set of one or more columns included in a FULLTEXT index. 集合是FULLTEXT索引中包含的一组一个或多个列。 The search string is given as the argument to AGAINST() . 搜索字符串作为AGAINST()的参数给出。 For each row in the table, MATCH() returns a relevance value; 对于表中的每一行, MATCH()返回一个相关性值; that is, a similarity measure between the search string and the text in that row in the columns named in the MATCH() list. 也就是说,在搜索字符串和MATCH()列表中命名的列中该行中的文本之间的相似性度量。

Natural Language Full-Text Searches 自然语言全文搜索

The query needs no optimization instead the table might if indexing is not done on that table. 查询不需要优化,而是如果未对该表进行索引,则该表可能不需要优化。

What is an index in SQL Server? 什么是SQL Server中的索引?

And for your scenario, ie text searching using wildcard, Full text indexing is recommended. 对于您的方案,即使用通配符的文本搜索,建议使用Full text indexing

When should you use full-text indexing? 什么时候应该使用全文索引?

Why not make a full-text search and index it? 为什么不进行全文搜索和索引呢? That will make searches much faster. 这样可以使搜索更快。 By using a LIKE query, especially one that is prefix wild-carded it means every row has to be sequentially scanned. 通过使用LIKE查询,尤其是使用前缀通配符的查询,意味着必须按顺序扫描每一行。

https://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html https://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

I would make two-column full-text index on title,content : 我将在title,content上创建两列全文索引:

CREATE FULLTEXT INDEX index_content ON (title,content)

Than search on it like: 比像这样搜索:

SELECT ... WHERE MATCH(title, content) AGAINST ("your query")

Optionally using IN BOOLEAN MODE - read the docs for reasons on why you would and would not use this modifier. (可选)使用IN BOOLEAN MODE阅读文档,了解为何会使用和不会使用此修饰符的原因。

If you really cannot implement a full-text search+index and need to keep the LIKE then you can consider just adding a regular index on content , but then to take advantage of that index you will have to remove the leading wild-card (you can keep the trailing one); 如果你真的无法实现全文搜索+指数和需要保持LIKE那么你可以考虑只是添加普通索引content ,但随后利用该索引,你将不得不删除前导通配符(你可以保持尾随一个); MySQL cannot use an index on a leading-wildcard query. MySQL不能在前导通配符查询上使用索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM