Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL如何简化此查询并提高性能?_Mysql_Sql_Select - Fatal编程技术网

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

Mysql SQL如何简化此查询并提高性能?,mysql,sql,select,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 productword

我想可以用一种更简单的方式编写这个查询,它的性能会更好:

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”字样的不同ProductID的数量


谢谢

如果我正确理解了您的问题,那么使用
连接应该更好:

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

您当前对pw=w.id的查询实际上不正确。上面应该包括您试图加入的任何字段。我猜是
productid
,但可能是它的
wordid

如果我正确理解了您的问题,那么使用
连接就更好了:

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

您当前对pw=w.id的查询实际上不正确。上面应该包括您试图加入的任何字段。我猜是
productid
,但也许它的
wordid
相反…

您可以这样简单地执行查询

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
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
希望这个问题能回答你的问题。 你也可以通过

where w.name in ('nike', 'free')
如果你有很多行(比如10000++),你可以这样改进

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
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

您可以这样简单地执行查询

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
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
希望这个问题能回答你的问题。 你也可以通过

where w.name in ('nike', 'free')
如果你有很多行(比如10000++),你可以这样改进

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
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

非常奇怪的是,
productsworks
(productsworks?)表中的外键列名为
pw
,而不是
word\u id
。(但它只是一个列名,我们可以随意命名。如果外键实际命名为其他名称,则将下面查询中的
pw.pw
替换为
pw.column\u name
。)

要查找同时匹配这两个词的产品,请仅在产品与“nike”和“free”匹配时返回产品

我们可以使用连接操作,结合
GROUP BY
HAVING
子句

 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
还有其他查询模式将返回相同的结果

例如,使用
存在(相关子查询)
模式仅获取与两个指定单词匹配的产品

 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)

非常奇怪的是,
productsworks
(productsworks?)表中的外键列名为
pw
,而不是
word\u id
。(但它只是一个列名,我们可以随意命名。如果外键实际命名为其他名称,则将下面查询中的
pw.pw
替换为
pw.column\u name
。)

要查找同时匹配这两个词的产品,请仅在产品与“nike”和“free”匹配时返回产品

我们可以使用连接操作,结合
GROUP BY
HAVING
子句

 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
还有其他查询模式将返回相同的结果

例如,使用
存在(相关子查询)
模式仅获取与两个指定单词匹配的产品

 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)

发布一些示例数据和所需结果。请发布您的表结构和一些示例数据…发布一些示例数据和所需结果。请发布您的表结构和一些示例数据…我认为此查询返回与任一关键字匹配的产品计数。这可能是OP的意图,但我对规范的理解有点不同。。。返回计数。。。但仅包括符合关键字“nike”和关键字“free”的产品。(如果产品与“nike”匹配,但与“free”不匹配,则该产品将不包括在内。)您是对的,返回的产品必须同时匹配两个关键字,即“nike”和“free”。我已修复了“on pw=w.id”中的错误-应该是“on pw.wordid=w.id”我认为这个查询返回的产品数量与关键字匹配。这可能是OP的意图,但我对规范的理解有点不同。。。返回计数。。。但仅包括符合关键字“nike”和关键字“free”的产品。(如果某个产品与“nike”匹配,但与“free”不匹配,则该产品将不包括在内。)你是对的,返回的产品必须同时匹配两个关键字,即“nike”和“free”。我已修复了“on pw=w.id”中的错误-应该是“on pw.wordid=w.id”。这确实是一个更简单的查询。但这也会返回与OP查询结果显著不同的结果。这将返回与每个
单词相关的行数。这可能是OP想要的结果,但我阅读规范的方式完全不同,返回了与OP查询相同的结果。哦,对不起,我忘记插入过滤器了。我将编辑我的答案。这确实是一个比较简单的问题。但这也会返回与OP查询结果显著不同的结果。这将返回与每个
单词相关的行数。这可能是OP想要的结果,但我阅读规范的方式完全不同,返回了与OP查询相同的结果。哦,对不起,我忘记插入过滤器了。我将编辑我的答案。