2016-09-14 75 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