SQL如何简化此查询并提高性能?

时间:2016-10-08 01:26:04

标签: mysql sql select

我想这个查询可以用更简单的方式编写,效果更好:

SELECT COUNT(DISTINCT productid)
FROM productwords pw
WHERE productid IN
(SELECT productid FROM productwords pw JOIN words w 
  ON pw.wordid = w.id WHERE word = 'nike')
AND productid IN 
(SELECT productid FROM productwords pw JOIN words w 
  ON pw.wordid = w.id WHERE word = 'free')

查询的目标是获得具有单词='nike'和'free'的不同产品的数量。

谢谢!

3 个答案:

答案 0 :(得分:4)

如果我正确理解您的问题,那么使用join

会更好
SELECT COUNT(DISTINCT productid)
FROM productwords pw
   JOIN words w ON pw.productid = w.id 
WHERE word IN ('nike','free')

您当前的查询on pw = w.id实际上并不正确。您尝试join的任何字段都应包含在上方。我猜到productid,但也许是wordid而不是......

答案 1 :(得分:0)

您可以通过这样做来简单地进行查询

select count(*), w.word from product p left join words w on w.id = p.word_id where w.name = 'nike' or w.name = 'free' group by w.name

希望此查询能够回答您的问题。 你也可以过滤

where w.name in ('nike', 'free')

如果你有很多行(让我们说10,000 ++),你可以像这样改进

SELECT count(*), w.name from product p JOIN (select id, name from words where name = 'nike' or name = 'free') w on w.id = p.word_id group by w.name

答案 2 :(得分:0)

很奇怪productswords(产品剑?)表中的外键列是pw,而不是word_id。 (但它只是一个列名,我们可以将它命名为我们想要的任何名称。如果外键实际上是其他名称,那么在下面的查询中用pw.pw替换pw.column_name ...)

要找到与这两个单词相匹配的产品,意味着,只有与“nike”一词匹配的产品才会返回,并且如果它与“免费”一词匹配...

我们可以使用联接操作,结合GROUP BYHAVING条款......

 SELECT pw.productid 
   FROM productwords pw
   JOIN words w 
     ON w.id = pw.pw
    AND w.word IN ('nike','free')   -- keywords to match
  GROUP BY pw.productid
 HAVING COUNT(DISTINCT w.word) = 2  -- number of keywords to match

为了得到一个计数,我们可以在查询中将其包装在parens中并将其作为内联视图引用...

 SELECT COUNT(1)
   FROM ( SELECT pw.productid 
            FROM productwords pw
            JOIN words w 
              ON w.id = pw.pw
             AND w.word IN ('nike','free')   -- keywords you are looking for
           GROUP BY pw.productid
          HAVING COUNT(DISTINCT w.word) = 2  -- number of keywords to match
        ) v

还有其他查询模式会返回相同的结果。

例如,使用 EXISTS (correlated subquery) 模式只获取与指定字词匹配的产品......

 SELECT pw.productid
   FROM productwords pw
  WHERE EXISTS ( SELECT 1
                   FROM words w
                  WHERE w.id = pw.pw      -- related to row on outer query
                    AND w.word IN ('nike','free')
               )
 GROUP BY pw.productid
HAVING COUNT(DISTINCT pw.pw) = 2

要获得一个计数,再次将其包装在parens中并将其作为内联视图引用。

对于非平凡集,使用合适的索引可以显着提高两个查询的性能。例如

   ... ON productswords (pw, productid)
   ... ON words (word, id)