如何使用两个内部联接优化查询

时间:2016-09-14 12:55:19

标签: mysql select inner-join

使用此查询获取包含满足所有三个必需字词(lenovo,笔记本电脑,计算机)的字词的产品:

SELECT t1.id, t1.name, t1.price FROM
(SELECT p.id AS productid, name, price 
FROM products p JOIN productwords pw ON p.id = pw.productid 
JOIN words w ON pw.wordid = w.id WHERE word.term = 'lenovo') t1
INNER JOIN
(SELECT p.id AS productid, name, price
FROM products p JOIN productwords pw ON p.id = pw.productid 
JOIN words w ON pw.wordid = w.id WHERE word.term = 'laptop') t2
INNER JOIN
(SELECT p.id AS productid, name, price
FROM products p JOIN productwords pw ON p.id = pw.productid 
JOIN words w ON pw.wordid = w.id WHERE word.term = 'computer') t3
ON
t1.productid = t2.productid
AND
t1.productid = t3.productid
ORDER BY t1.name

据我所知,查询考虑了每个术语的整个单词表(表中有索引。数据库是MySql)。

可以更好地重写查询,因此它会变得更快吗? (这些表包含数百万行)

例如对于子集,所以'笔记本电脑'搜索只考虑匹配' lenovo' - 和计算机'搜索只会考虑首先匹配的行! lenovo'然后是笔记本电脑'。

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用HAVING子句:

SELECT p.id AS productid, name, price 
FROM products p
JOIN productwords pw ON p.id = pw.productid 
JOIN words w ON pw.wordid = w.id
WHERE word.term in ('lenovo','computer','laptop')
GROUP BY p.id , name, price 
HAVING COUNT(DISTINCT word.term) = 3

如果我理解了这个问题,它看起来像产品 - >单词是1:n关系,如果没有选择word表中的列,那应该是完美的。

答案 1 :(得分:0)

这可能是一种更快捷的方法:

SELECT p.id, name, price FROM products p where EXISTS (select null from productwords pw1 JOIN words w1 ON pw1.wordid = w1.id where w1.term = 'lenovo' and p.id = pw1.productid ) and EXISTS (select null productwords pw2 JOIN words w2 ON pw2.wordid = w2.id where w2.term = 'laptop' and and p.id = pw2.productid ) and EXISTS (select null productwords pw3 ON p.id = pw3.productid JOIN words w3 where w3.term = 'computer' and p.id = pw3.productid )
ORDER BY name;