左连接与内连接的查询性能 - MySQL

时间:2016-07-06 06:57:31

标签: mysql sql join left-join inner-join

我想知道2个查询之间的区别。我有2个表:用户和电子邮件。

User schema - id, name, email, is_subscribed, created, modified.

Email schema - id, user_id, sent_at, subject.

因此,我需要查找那些已经收到超过20封电子邮件的用户

用户表大致围绕 100K记录。电子邮件表有近 400万条记录

第一次查询

SELECT u.id, u.email, count(u.id)
FROM emails as e
LEFT JOIN users as u
ON e.user_id = u.id
WHERE u.is_subscribed = 1
GROUP BY e.user_id HAVING count(u.id) > 20

第二次查询

SELECT u.id, u.email, count(u.id)
FROM users as u
INNER JOIN emails as e
ON e.user_id = u.id
WHERE u.is_subscribed = 1
GROUP BY e.user_id HAVING count(u.id) > 20

我尝试过:

1)在生产中,这些查询需要永远执行,所以在本地,我创建了带有虚拟记录的样本表。即

用户表 - 大约有5条记录和大约100条记录的电子邮件表。

当我执行上述两个查询时,我为两个查询获得了相同的结果集,当检查了性能分析时,我得到两个查询的相同执行时间(生产时可能会有所不同)所以很难知道哪个更好。 (这可能不是找到解决方案的最佳方式。)

2)对查询使用Explain,并显示在两种情况下(查询)扫描所有 100行电子邮件表

如果我遗漏了任何细节,请告诉我。我会更新这个问题。

2 个答案:

答案 0 :(得分:0)

请尝试以下查询: -

SELECT u.id, u.email, count(u.id)
FROM users as u
INNER JOIN emails as e ON e.user_id = u.id
WHERE u.is_subscribed = 1
GROUP BY u.id 
HAVING count(u.id) > 20

答案 1 :(得分:0)

了解MySQL LEFT JOIN optimization。 DBMS可以告诉您LEFT JOIN s WHERE正在过滤掉来自LEFT JOIN的所有来自INNER JOIN的NULL扩展行,因此它只会执行INNER JOIN

  

MySQL 5.7参考手册
  9.2.1.9 LEFT JOIN和RIGHT JOIN优化

     

对于LEFT JOIN,如果生成的NULL行的WHERE条件始终为false,则LEFT JOIN将更改为普通连接。

(因为你不想要NULL扩展行,为什么要使用LEFT JOIN?)