mysql:double condition WHERE LIKE减慢SELECT查询速度

时间:2017-01-06 18:06:30

标签: mysql database

我有两张桌子:

<span class="wrapper">
  <input class="wideinput">
</span>

<span class="wrapper">
  <input class="narrowinput">
</span>

<span class="wrapper">
  <span>text</span>
</span>

POSTS (about 2000 rows)
ID  title

基本上,如果searchterm在posts.title或elements.elementname中,我想返回ID。我使用以下查询:

ELEMENTS (about 60000 rows)
postID (fK)    elementfield

它有效,但它非常慢(大约40秒!)。

我认为它是元素表的大小(超过60.000行),但如果我只使用一个WHERE子句运行相同的查询

SELECT SQL_CALC_FOUND_ROWS posts.ID 
FROM posts 
LEFT JOIN elements 
ON posts.ID = elements.postID 
WHERE (
  posts.post_title LIKE '%searchterm%' 
  OR elements.elementfield LIKE '%searchterm%' 
  ) 

它会在几秒钟内返回查找...

我不是数据库专家,但这看起来很基本......我做错了什么?谢谢你的帮助!

EDIT @Solarflare运行EXPLAIN 我有这样的事情:

WHERE  elements.elementfield LIKE '%searchterm%' 

2 个答案:

答案 0 :(得分:1)

在where子句中使用Or是众所周知的无效性。试试这个:

SELECT SQL_CALC_FOUND_ROWS p.ID 
FROM posts p
  LEFT JOIN elements e
    ON p.ID = e.postID 
WHERE CONCAT(p.post_title, e.elementfield) LIKE '%searchterm%' 
顺便说一句,什么是SQL_CALC_FOUND_ROWS,一个内置函数?

答案 1 :(得分:1)

  

它会在几秒钟内返回查找...

这很快得益于MySQL query cache。如果使用跳过查询缓存的选项运行查询,您会发现它再次运行缓慢:

SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS posts.ID 
FROM posts 
LEFT JOIN elements 
ON posts.ID = elements.postID 
WHERE elements.elementfield LIKE '%searchterm%'

LIKE '%pattern%'的任何查询都必须进行表扫描。该谓词不能使用索引。

请参阅我的演示文稿Full Text Search Throwdown

您可以在每张桌子上创建一个FULLTEXT INDEX并使用MATCH() function

但是你不能创建一个跨越多个表的索引(参见我对mySQL MATCH across multiple tables的回答)。

你在评论中提到:

  

SQL_CALC_FOUND_ROWS在wordpress中

这是否意味着您没有机会更改SQL查询(除了更改Wordpress代码)?如果是这样,那你就不走运了。使用Wordpress提交错误修复请求。

在某些情况下,SQL_CALC_FOUND_ROWS查询修饰符会对查询造成巨大的性能损失。取决于数据集的大小以及是否有索引来帮助查询。但是你应该使用和不使用SQL_CALC_FOUND_ROWS测试你的查询,看看哪个更快。