简体   繁体   中英

How to optimize query with two inner join

Using this query to get the products with words that fulfill all three required word terms (lenovo, laptop, computer):

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

As far as I can see, the query considers the whole words table for each term (the tables have indexes. Database is MySql).

Can the query be rewritten in a better way, so it will become faster? (the tables contain millions of rows)

For example with subsets, so the 'laptop' search only considers the rows matching 'lenovo' - and the 'computer' search only considers the rows matching first 'lenovo' and then 'laptop'.

Thanks!

You can use the HAVING clause :

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

That is if I understood the question, it looks like product -> words is 1:n relation , and if no column from the word table is selected, that should work perfectly.

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

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM