我有一个类似
的查询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
仅使用原始查询有哪些优点/缺点?
<小时/> 的更新
所以我将用原始查询的解释来更新它。
此查询导致我的服务器使用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
答案 0 :(得分:5)
只需使用原始查询即可。 MySQL optimizes这种情况可以,特别是如果mobile
是索引列的话。它只运行一次非相关子查询,并合理有效地将to_number
与mobile
个数字进行比较。
我不知道在查询和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%(可能因数据而异;对于小数据,差异可能无法衡量)。