非常慢的MySQL子查询

时间:2015-02-20 06:19:03

标签: mysql

我有两个表,每个表包含大约500个客户数据记录。每个表中的每条记录都有一个电子邮件字段。有时两个表上都存在相同的电子邮件地址,有时则不存在。我想检索table1上table2上不存在的每个电子邮件地址。每个表中的电子邮件字段都已编制索引。我正在使用一个非常慢的子查询进行选择,10到20秒。

select email
from
t1
where
email not in (select email from t2)

每张桌子实际上有大约30K行,但是我可以很快将其击倒到500,并且按类别过滤“where”。只有当我添加子查询时它才会显着减速。所以,我确信这可以更快,我知道连接应该比子查询快得多,但无法弄清楚如何做到这一点。我在SO上找到了一个左外连接解释,看起来应该有所帮助,但无处可去。任何帮助表示赞赏。

4 个答案:

答案 0 :(得分:4)

mysql不优化WHERE子句中的子查询(编辑:它为每个测试的行重新运行子查询)

转换为JOIN,尝试类似

的内容
SELECT email FROM t1
LEFT JOIN t2 ON (t1.email = t2.email)
WHERE t2.email IS NULL

这应该运行得非常快,一个覆盖索引查询。 查询优化器应该走t1的电子邮件索引,检查 电子邮件索引为t2,并输出那些在t1但不在t2中的电子邮件。

编辑:我应该添加,mysql 优化JOIN子句中的子查询:它运行子查询并将结果放入“派生表”(没有任何索引的临时表)和连接派生表和其他任何表一样。语法有点滑稽,每个派生表必须有一个别名,即... JOIN (SELECT ...) AS derived ON ...

答案 1 :(得分:2)

通常,子查询比常规查询执行更多处理。在您的情况下,它首先从t2获取所有电子邮件,并将其与t1的电子邮件列表进行比较。

您可以尝试如下,而不使用子查询。

SELECT email FROM t1,t2 WHERE t1.email!=t2.email 

答案 2 :(得分:1)

提高SELECT操作性能的最佳方法是在查询中测试的一个或多个列上创建索引。索引条目的作用类似于表行的指针,允许查询快速确定哪些行与WHERE子句中的条件匹配,并检索这些行的其他列值。可以索引所有MySQL数据类型。

创建mysql表的一些技巧.. see this.

答案 3 :(得分:0)

我认为这应该可以正常使用

SELECT email from T1
LEFT JOIN T2
ON T1.email=T2.email
WHERE T2.email!=NULL