MySQL:内部联接vs Where

时间:2011-03-11 14:10:37

标签: mysql sql performance inner-join

之间的性能(在mysql中)是否存在差异
Select * from Table1 T1 
Inner Join Table2 T2 On T1.ID = T2.ID

Select * from Table1 T1, Table2 T2 
Where T1.ID = T2.ID

8 个答案:

答案 0 :(得分:12)

他们是一样的。通过运行EXPLAIN命令可以看到这一点:

mysql> explain Select * from Table1 T1 
    -> Inner Join Table2 T2 On T1.ID = T2.ID;
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                                       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------------+
|  1 | SIMPLE      | T1    | index | PRIMARY       | PRIMARY | 4       | NULL |    4 | Using index                                 |
|  1 | SIMPLE      | T2    | index | PRIMARY       | PRIMARY | 4       | NULL |    4 | Using where; Using index; Using join buffer |
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------------+
2 rows in set (0.00 sec)

mysql> explain Select * from Table1 T1, Table2 T2 
    -> Where T1.ID = T2.ID;
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                                       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------------+
|  1 | SIMPLE      | T1    | index | PRIMARY       | PRIMARY | 4       | NULL |    4 | Using index                                 |
|  1 | SIMPLE      | T2    | index | PRIMARY       | PRIMARY | 4       | NULL |    4 | Using where; Using index; Using join buffer |
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------------+
2 rows in set (0.00 sec)

答案 1 :(得分:10)

从问题44917中接受的答案中删除:

  

性能方面,他们正是如此   相同(至少在SQL Server中)但是   意识到他们正在弃用   隐式外连接语法。

在MySql中,结果是一样的。

我个人坚持明确加入表格......这是"社会可接受的"这样做的方式。

答案 2 :(得分:2)

我的一个迟到的回答,因为我正在分析使用基于逗号的连接而不是INNER JOIN子句的旧应用程序的性能。

所以这里有两个有连接的表(两个都有超过1个lac的记录)。执行具有基于逗号的连接的查询时,它比INNER JOIN情况需要更长的时间。

当我分析explain语句时,我发现使用逗号连接的查询使用了连接缓冲区。但是,具有INNER JOIN子句的查询具有“使用位置”。

这些查询也有很大不同,如解释查询中的rows列所示。 这些是我的查询及其各自的解释结果。

explain select count(*) FROM mbst a , his_moneypv2 b 
        WHERE b.yymm IN ('200802','200811','201001','201002','201003') 
        AND a.tel3 != '' 
        AND a.mb_no = b.mb_no 
        AND b.true_grade_class IN (3,6)
        OR b.grade_class IN (4,7);

+----+-------------+-------+-------------+----------------------------------------------------------------+--------------------------------------+---------+------+--------+---------------------------------------------------------------------+
| id | select_type | table | type        | possible_keys                                                  | key                                  | key_len | ref  | rows   | Extra                                                               |
+----+-------------+-------+-------------+----------------------------------------------------------------+--------------------------------------+---------+------+--------+---------------------------------------------------------------------+
|  1 | SIMPLE      | b     | index_merge | PRIMARY,mb_no,yymm,yymm_2,idx_true_grade_class,idx_grade_class | idx_true_grade_class,idx_grade_class | 5,9     | NULL |  16924 | Using sort_union(idx_true_grade_class,idx_grade_class); Using where |
|  1 | SIMPLE      | a     | ALL         | PRIMARY                                                        | NULL                                 | NULL    | NULL | 134472 | Using where; Using join buffer                                      |
+----+-------------+-------+-------------+----------------------------------------------------------------+--------------------------------------+---------+------+--------+---------------------------------------------------------------------+

V / S

explain select count(*) FROM mbst a inner join his_moneypv2 b 
        on a.mb_no = b.mb_no 
        WHERE b.yymm IN ('200802','200811','201001','201002','201003') 
        AND a.tel3 != '' 
        AND b.true_grade_class IN (3,6) 
        OR b.grade_class IN (4,7);

 +----+-------------+-------+-------------+----------------------------------------------------------------+--------------------------------------+---------+--------------------+-------+---------------------------------------------------------------------+
 | id | select_type | table | type        | possible_keys                                                  | key                                  | key_len | ref                | rows  | Extra                                                               |
 +----+-------------+-------+-------------+----------------------------------------------------------------+--------------------------------------+---------+--------------------+-------+---------------------------------------------------------------------+
 |  1 | SIMPLE      | b     | index_merge | PRIMARY,mb_no,yymm,yymm_2,idx_true_grade_class,idx_grade_class | idx_true_grade_class,idx_grade_class | 5,9     | NULL               | 16924 | Using sort_union(idx_true_grade_class,idx_grade_class); Using where |
 |  1 | SIMPLE      | a     | eq_ref      | PRIMARY                                                        | PRIMARY                              | 62      | shaklee_my.b.mb_no |     1 | Using where                                                         |
 +----+-------------+-------+-------------+----------------------------------------------------------------+--------------------------------------+---------+--------------------+------

答案 3 :(得分:1)

实际上它们实际上是相同的,JOIN / ON是较新的ANSI语法,WHERE是较旧的ANSI语法。两者都被查询引擎识别

答案 4 :(得分:0)

FROM子句中的逗号是CROSS JOIN。我们可以想象SQL服务器有一个select查询执行过程,它应该看起来像这样: 1.遍历每个表格 2.找到满足连接谓词的行并将其放入结果表中。 3.从结果表中,仅获取满足where条件的那些行。

如果它真的如此,那么在具有几千行的表上使用CROSS JOIN可以分配大量内存,当每行在检查where条件之前相互组合时。你的SQL服务器可能很忙。

答案 5 :(得分:0)

我会这么认为,因为第一个示例明确告诉mysql要加入哪些列以及如何连接它们,其中第二个mysql必须尝试找出你想要加入的位置。

答案 6 :(得分:0)

第二个查询只是内部联接的另一种表示法,所以如果在性能上存在差异,那只是因为一个查询可以比另一个查询更快地解析 - 而且如果它存在,那么差异将会非常小你不会注意到它。

有关详细信息,您可以尝试查看this question(并在下一次使用SO搜索之后再询问已经回答的问题)

答案 7 :(得分:0)

MySQL的第一个查询更容易理解,因此执行计划可能更好,查询运行得更快。

没有where子句的第二个查询是交叉连接。如果MySQL能够理解where子句足够好,它将尽力避免交叉连接所有行,但没有任何保证。

在像您这样简单的情况下,性能将严格相同。

性能方面,第一个查询总是与第二个查询更好或相同。从我的观点来看,重读时也更容易理解。