使用" ON .. AND"之间的区别和"在哪里"在LEFT JOIN中

时间:2016-06-26 17:58:08

标签: mysql database-performance

这两个查询是否与执行角度有效相同或者它们之间存在差异?如果它们相同,那么这两者之间会有任何性能差异吗?

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

2 个答案:

答案 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可以影响数据库执行查询的方式。