这两个查询是否与执行角度有效相同或者它们之间存在差异?如果它们相同,那么这两者之间会有任何性能差异吗?
1
SELECT *
FROM TABLE_A tbl_a
LEFT JOIN TABLE_B tbl_b ON (tbl_a.srno_a = tbl_b.srno_b)
AND tbl_a.srno_a = 1997
和
2
SELECT *
FROM TABLE_A tbl_a
LEFT JOIN TABLE_B tbl_b ON (tbl_a.srno_a = tbl_b.srno_b)
WHERE tbl_a.srno_a = 1997
答案 0 :(得分:2)
在这里你可以看到差异:
如果使用WHERE,结果会更小。看看样本。
<强>样品强>
我的表格
MariaDB [yourSchema]> select * from table1;
+--------+------------+
| id | val |
+--------+------------+
| 000001 | tabe 1 --1 |
| 000002 | tabe 1 --2 |
| 000003 | tabe 1 --3 |
| 000004 | tabe 1 --4 |
| 000005 | tabe 1 --5 |
| 000006 | tabe 1 --6 |
+--------+------------+
6 rows in set (0.00 sec)
MariaDB [yourSchema]> select * from table2;
+--------+------------+
| id | val |
+--------+------------+
| 000001 | tabe 2 --1 |
| 000002 | tabe 2 --2 |
| 000004 | tabe 2 --4 |
| 000005 | tabe 2 --5 |
| 000006 | tabe 2 --6 |
+--------+------------+
5 rows in set (0.00 sec)
MariaDB [yourSchema]>
加入AND
MariaDB [yourSchema]> SELECT *
-> FROM table1 t1
-> LEFT JOIN table2 t2 ON t1.id = t2. id AND t2.val ='tabe 2 --4';
+--------+------------+--------+------------+
| id | val | id | val |
+--------+------------+--------+------------+
| 000004 | tabe 1 --4 | 000004 | tabe 2 --4 |
| 000001 | tabe 1 --1 | NULL | NULL |
| 000002 | tabe 1 --2 | NULL | NULL |
| 000003 | tabe 1 --3 | NULL | NULL |
| 000005 | tabe 1 --5 | NULL | NULL |
| 000006 | tabe 1 --6 | NULL | NULL |
+--------+------------+--------+------------+
6 rows in set (0.00 sec)
MariaDB [yourSchema]>
加入WHERE
MariaDB [yourSchema]> SELECT *
-> FROM table1 t1
-> LEFT JOIN table2 t2 ON t1.id = t2. id
-> WHERE t2.val ='tabe 2 --4';
+--------+------------+--------+------------+
| id | val | id | val |
+--------+------------+--------+------------+
| 000004 | tabe 1 --4 | 000004 | tabe 2 --4 |
+--------+------------+--------+------------+
1 row in set (0.00 sec)
MariaDB [yourSchema]>
答案 1 :(得分:1)
对于LEFT [OUTER] JOIN
, 是基于多重性的基本差异。这是因为LEFT / RIGHT / FULL外连接&#39;保留&#39;分别存在于左/右源集中的记录,即使它们不匹配:
即:左连接会不删除左侧设置中显示的所有行,无论连接条件如何。
-- the result of the LEFT join contains every LEFT row AT LEAST ONCE
-- then we throw away the post-join rows that we don't want
SELECT * FROM l
LEFT JOIN r ON r.id = l.id
WHERE l.x = q
-- the above is logically equivalent to the following
-- where the left set is restricted before the join
SELECT * FROM (SELECT * FROM l WHERE l.x = q) l2
LEFT JOIN r ON r.id = l2.id
-- however, it differs from just moving the condition as
-- the result of the LEFT join contains every LEFT row AT LEAST ONCE
-- (this includes the rows for which 'l.x = q' is NOT true!)
-- but we don't filter the post-join rows
SELECT * FROM l
LEFT JOIN r ON r.id = l.id
AND l.x = q
使用OUTER JOIN
时,无法始终移动条件。对于LEFT JOIN
,限制性连接条件仅依赖 左侧关系,它可能是错误的。
如果是INNER JOIN
,则可以移动条件而不影响结果。这是因为INNER JOIN 限制两个已连接的集合,因此没有“至少”这样的情况。子句。
只有有效的查询才能理解性能 - 并且查询执行计划将包含相关的执行信息。使用&#39;正确&#39; join可以影响数据库执行查询的方式。