联接顺序在SQL中重要吗?

忽略性能,我将从下面的查询A和B得到相同的结果吗?C和D呢?

----- Scenario 1:
-- A (left join)
select *
from   a left join b
on <blahblah>
left join c
on <blahblan>




-- B (left join)
select *
from   a left join c
on <blahblah>
left join b
on <blahblan>


----- Scenario 2:
-- C (inner join)
select *
from   a join b
on <blahblah>
join c
on <blahblan>




-- D (inner join)
select *
from   a join c
on <blahblah>
join b
on <blahblan>
198832 次浏览

对于INNER连接,不,顺序不重要。查询将返回相同的结果,只要您将选择从SELECT *更改为SELECT a.*, b.*, c.*


对于(LEFTRIGHTFULL) OUTER连接,是的,顺序很重要-而(< em > < / em >更新)事情要复杂得多。

首先,外部连接是不可交换的,所以a LEFT JOIN bb LEFT JOIN a是不同的

外部连接也不是结合的,所以在你的例子中,涉及(交换性和结合性)属性:

a LEFT JOIN b
ON b.ab_id = a.ab_id
LEFT JOIN c
ON c.ac_id = a.ac_id

等于:

a LEFT JOIN c
ON c.ac_id = a.ac_id
LEFT JOIN b
ON b.ab_id = a.ab_id

但是:

a LEFT JOIN b
ON  b.ab_id = a.ab_id
LEFT JOIN c
ON  c.ac_id = a.ac_id
AND c.bc_id = b.bc_id

并不等同于:

a LEFT JOIN c
ON  c.ac_id = a.ac_id
LEFT JOIN b
ON  b.ab_id = a.ab_id
AND b.bc_id = c.bc_id

另一个(希望更简单)结合性的例子。可以把它看成(a LEFT JOIN b) LEFT JOIN c:

a LEFT JOIN b
ON b.ab_id = a.ab_id          -- AB condition
LEFT JOIN c
ON c.bc_id = b.bc_id          -- BC condition

是等价的a LEFT JOIN (b LEFT JOIN c):

a LEFT JOIN
b LEFT JOIN c
ON c.bc_id = b.bc_id          -- BC condition
ON b.ab_id = a.ab_id          -- AB condition

只是因为我们有“nice”ON条件。ON b.ab_id = a.ab_idc.bc_id = b.bc_id都是相等性检查,不涉及NULL比较。

你甚至可以使用其他操作符或更复杂的操作符,如ON a.x <= b.xON a.x = 7ON a.x LIKE b.xON (a.x, a.y) = (b.x, b.y),这两个查询仍然是等效的。

然而,如果这些查询中的任何一个涉及IS NULL或与空值相关的函数,如COALESCE(),例如如果条件是b.ab_id IS NULL,那么这两个查询将不相等。

对于常规的join,则不会。TableA join TableB将产生与TableB join TableA相同的执行计划(因此您的C和D示例将是相同的)

对于左右连接是这样的。TableA left Join TableBTableB left Join TableA不同,但与TableB right Join TableA相同

如果你在加入B之前尝试在B的一个字段上加入C,即:

SELECT A.x,
A.y,
A.z
FROM A
INNER JOIN C
on B.x = C.x
INNER JOIN B
on A.x = B.x

您的查询将失败,因此在这种情况下顺序很重要。

甲骨文优化器为内部连接选择表的连接顺序。 优化器只在简单FROM子句中选择表的连接顺序。 你可以在他们的网站上查看oracle文档。 对于左,右外加入,投票最多的答案是对的。 优化器为每个表选择最佳连接顺序和最佳索引。联接顺序会影响哪个索引是最佳选择。如果一个表是内部表,优化器可以选择一个索引作为它的访问路径,但如果它是外部表(并且没有进一步的限定条件)则不能

优化器只在简单FROM子句中选择表的连接顺序。使用JOIN关键字的大多数连接都被简化为简单连接,因此优化器会选择它们的连接顺序。

优化器不会为外部连接选择连接顺序;它使用语句中指定的顺序。

当选择连接顺序时,优化器会考虑: 每个桌子的大小 每个表上可用的索引 表上的索引在特定的连接顺序中是否有用 每个联接顺序中每个表要扫描的行数和页数