2016-09-14 67 views
0

使用此查询来获取与履行所有三项必需的词项(联想,笔记本电脑,计算机)字样的产品优化查询:如何使用两个内部加入

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'的行,然后'笔记本电脑'。

谢谢!

+0

见http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for什么似乎对我来说是一个非常简单的sql查询 – Strawberry

回答

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表列,这应该是完美的。

+0

好的一个。对于匹配30个产品的查询,性能从0,027秒变为0,015秒。谢谢! – Louisa

+0

没问题:) @Louisa – sagi

+0

你也有一招吗? http://stackoverflow.com/questions/39518561/getting-the-number-of-matches-for-various-word-combinations – Louisa

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;

+0

它可能会是相同的 – sagi