已解决:Andy Lester指出了正确的方向,这是由于索引定义不佳。
有一部分查询导致我遇到很多麻烦:
SELECT i.id
FROM items AS i
LEFT JOIN tag_rel as tr2 ON (tr2.item = i.id)
LEFT JOIN tags AS t2 ON (t2.id = tr2.tag)
WHERE t2.name LIKE 'chocolate'
GROUP BY i.id
项目是“项目表
”tag_rel 是商品与商品
之间的关系标记包含标记的名称
所以上面的查询工作正常,因为它应该:它返回标记为巧克力
的项目但是这就是我正在做的事情,这会减慢查询速度(10秒+)所以我猜我做错了什么: - /
SELECT i.id
FROM items AS i
LEFT JOIN tag_rel as tr2 ON (tr2.item = i.id)
LEFT JOIN tags AS t2 ON (t2.id = tr2.tag AND t2.sec_corrected = 0)
LEFT JOIN tags AS t3 ON (t3.sec_corrected = tr2.tag AND t3.sec_corrected > 0)
WHERE (t2.name LIKE 'choclate' OR t3.name LIKE 'choclate')
GROUP BY i.id
sec_corrected 是“tags”表中的一列,其中包含另一个标记的ID,即:
Tags table structure:
id 1 name choclate sec_corrected 2
id 2 name chocolate sec_corrected 0
只是为了澄清,如果用户搜索“巧克力”或“巧克力”,我想获得标记为“巧克力”的“商品”,因为“choclate”已被更正为“巧克力”。
我也尝试过只有一个LEFT JOIN,但它仍然很慢:
SELECT i.id
FROM items AS i
LEFT JOIN tag_rel as tr2 ON (tr2.item = i.id)
LEFT JOIN tags AS t2 ON (t2.id = tr2.tag OR t2.sec_corrected = tr2.tag)
WHERE (t2.name LIKE 'choclate')
GROUP BY i.id
有什么想法吗?
非常感谢你!
答案 0 :(得分:0)
如果没有解释,它有点Try-And-Error,但通常使用简单的“OR”子句可以阻止索引使用。 LIKE是矫枉过正的,当没有给出模式时使用“=”。
简单的解决方案是使用union将其拆分为两个INNER JOIN。丑陋,但往往很有帮助。
SELECT i.id
FROM items AS i
INNER JOIN tag_rel as tr2 ON (tr2.item = i.id)
INNER JOIN tags AS t2 ON (t2.id = tr2.tag AND t2.sec_corrected = 0)
WHERE (t2.name = 'choclate')
UNION
SELECT i.id
FROM items AS i
INNER JOIN tag_rel as tr2 ON (tr2.item = i.id)
INNER JOIN tags AS t3 ON (t3.sec_corrected = tr2.tag AND t3.sec_corrected > 0)
WHERE (t3.name = 'choclate')
这可能会有很大帮助。