之间的性能(在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
答案 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子句足够好,它将尽力避免交叉连接所有行,但没有任何保证。
在像您这样简单的情况下,性能将严格相同。
性能方面,第一个查询总是与第二个查询更好或相同。从我的观点来看,重读时也更容易理解。