在这里/哪里有用?

时间:2010-10-14 00:05:59

标签: mysql

我有一个类似

的查询
SELECT to_number FROM sent_texts 
WHERE to_number NOT IN(SELECT mobile FROM action_6_members);

在查询完成后,WHERE应用于结果集
如果子查询包含

,效果是什么(改善/降级)
WHERE mobile = to_number

查询期间,HAVING将应用于结果集
如果子查询包含

,效果是什么(改善/降级)
HAVING mobile = to_number

仅使用原始查询有哪些优点/缺点?

<小时/> 的更新
由于Bill Karwin's answer,我的初步想法似乎是错误的。

所以我将用原始查询的解释来更新它。

此查询导致我的服务器使用100%的cpu。

也许有人可以说出原因,以及如何解决它?

id  select_type         table             type   possible_keys  key        key_len  ref  rows    Extra                     
2   DEPENDENT SUBQUERY  action_6_members  index                 mobile     42            179218  Using where; Using index  
1   PRIMARY             sent_txts         index                 to_number  123           256066  Using where; Using index   

这是基于联接的解释(在更多优化之后)

id  select_type  table             type   possible_keys  key        key_len  ref  rows    Extra                                 
1   SIMPLE       sent_txts         index                 to_number  78            256066  Using index                           
1   SIMPLE       action_6_members  index                 mobile     27            179218  Using where; Using index; Not exists  

3 个答案:

答案 0 :(得分:5)

只需使用原始查询即可。 MySQL optimizes这种情况可以,特别是如果mobile是索引列的话。它只运行一次非相关子查询,并合理有效地将to_numbermobile个数字进行比较。

我不知道在查询和WHERE条件在查询过程中应用HAVING条件后,您在哪里得到了关于WHERE条件的想法。这不准确。

这样想:

  • HAVING条件会从结果集中删除。这是在查询期间完成的。

  • GROUP BY条件会从结果集中删除。这也是在查询期间完成的,但在HAVING将行收集到组中之后。

    如果您不使用GROUP BY,则不应使用{{1}}。

答案 1 :(得分:0)

也许这个。 SELECT to_number FROM sent_texts 什么不存在(选择mobile FROM action_6_members where mobile = to_number);

我不确定它是否会有所帮助。尝试比较执行计划。

答案 2 :(得分:0)

我认为您在WHERE mobile = to_number找到的是一个相关的子查询:

SELECT to_number
FROM sent_texts
WHERE NOT EXISTS (
    SELECT 1
    FROM action_6_members
    WHERE mobile=sent_texts.to_number
);

通常,相关的子查询是不合需要的。但在这种情况下,MySQL应该将相关和原始子查询优化为同一种DEPENDENT SUBQUERY。您可以使用EXPLAIN SELECT ...对数据和索引进行检查。

在任何情况下,如果可以的话,通常最好在MySQL中使用连接而不是子查询。这个空连接:

SELECT to_number
FROM sent_texts
LEFT JOIN action_6_members ON action_6_members.mobile=to_number
WHERE action_6_members.mobile IS NULL

比我的子查询方法执行速度快33%(可能因数据而异;对于小数据,差异可能无法衡量)。