我有两张桌子:
<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%'
答案 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测试你的查询,看看哪个更快。