连接顺序在SQL中重要吗?
不管性能如何,我会从下面的查询A和查询B得到相同的结果吗?C和D呢连接顺序在SQL中重要吗?,sql,join,relational-database,Sql,Join,Relational Database,不管性能如何,我会从下面的查询A和查询B得到相同的结果吗?C和D呢 -- A select * from a left join b on <blahblah> left join c on <blahblan> -- B select * from a left join c on <blahblah> left join b on
-- A
select *
from a left join b
on <blahblah>
left join c
on <blahblan>
-- B
select *
from a left join c
on <blahblah>
left join b
on <blahblan>
-- C
select *
from a join b
on <blahblah>
join c
on <blahblan>
-- D
select *
from a join c
on <blahblah>
join b
on <blahblan>
对于内部联接,不,顺序不重要。只要将SELECT从SELECT*更改为SELECT a.*、b.*、c.*,查询将返回相同的结果
对于左连接、右连接或完全外部连接,是的,顺序很重要,更新的事情要复杂得多
首先,外部连接是不可交换的,因此左连接b与左连接a不同
外部联接也不是关联的,因此在涉及交换性和关联性属性的示例中:
a LEFT JOIN b
ON b.ab_id = a.ab_id
LEFT JOIN c
ON c.ac_id = a.ac_id
相当于:
但是:
不等同于:
另一个希望更简单的关联性示例。将其视为左连接b左连接c:
这相当于左连接b左连接c:
只是因为我们有很好的条件。在b.ab_id=a.ab_id和c.bc_id=b.bc_id上都是相等检查,不涉及空比较
您甚至可以使用其他运算符或更复杂的运算符来设置条件,例如:在a.x上,对于常规联接,它不会。TableA join TableB将生成与TableB join TableA相同的执行计划,因此您的C和D示例将是相同的
对于左连接和右连接,它是这样做的。TableA left Join TableB与TableB left Join TableA不同,但如果您在加入B之前尝试从B在字段上加入C,则与TableB right Join TableA相同,即:
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
您的查询将失败,因此在这种情况下,顺序很重要。Oracle optimizer为内部联接选择表的联接顺序。
优化器仅在简单FROM子句中选择表的联接顺序。
你可以在他们的网站上查看oracle文档。
对于左派,右派,投票最多的答案是右派。
优化器为每个表选择最佳连接顺序和最佳索引。连接顺序会影响哪个索引是最佳选择。如果是内部表,优化器可以选择索引作为表的访问路径,但如果是外部表,并且没有进一步的限定条件,则不能选择索引作为表的访问路径
优化器仅在简单FROM子句中选择表的联接顺序。大多数使用JOIN关键字的联接都被展平为简单联接,因此优化器选择它们的联接顺序
优化器不会为外部联接选择联接顺序;它使用语句中指定的顺序
选择联接顺序时,优化器会考虑:
每张桌子的大小
每个表上可用的索引
表上的索引在特定联接顺序中是否有用
每个联接顺序中每个表要扫描的行数和页数是多少?你是加入A到B和A到C,还是加入A到B和B到C?嗨,Beny,我问题中的代码是抽象的。我不关心将A连接到B或A连接到C,我只想知道这样的语法是否会提供相同的结果。更正确的说法是,外部连接是关联的,只要一个表中的所有列都为NULL的行不能满足任何谓词,而不是说它是关联的,只要谓词不涉及NULL或“与NULL相关的函数”。我们可以很容易地想象一个谓词满足前一种描述,但不满足后一种描述,如a.somecol>0或b.someothercol>0;关联性可能会在这种情况下失败。但是,我认为,从技术上讲,只要谓词不满足我在这里描述的任何一个条件,外部连接是关联的,这是正确的:第一个条件也会破坏内部连接的关联性,但这是一个如此廉价和明显的方法打破它,也许它不值得一提。还值得指出的是,最常见的连接方式——外键连接——不满足上述任何一种条件,因此具有良好的关联性。@MarkAmery谢谢你,我在这一点上很难构建我的句子,我已经对你的答案投了赞成票;我有一个内连接和一个左连接。它是这样工作的吗?首先查询将根据内部联接过滤记录,然后将左联接应用于过滤的记录?事实上,所有联接类型都是关联的,正如SQL标准和关联性的数学定义所规定的那样,但它们看起来并不关联,因为重新排列括号需要将ON子句(即join规范)移动到新位置。不过,这只是语法。如果使用关系代数表示法,其中连接规范位于连接运算符下方,则关联性变得更明显。您的参数只显示外部联接不是可交换的,这是正确的。这只说明了可交换性,但问题中的示例表明询问者对关联性感兴趣。ypercube的答案同时解决了这两个问题。是的,这是正确的,正确的答案应该是am
这是一个很好的答案。
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
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
ON c.bc_id = b.bc_id -- BC condition
ON b.ab_id = a.ab_id -- AB condition
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