3

以典型的左外连接场景为例。我们都知道表格的顺序非常重要,例如,Q1Q2是不等价的:

SELECT A.x, B.y FROM A LEFT OUTER JOIN B ON A.id = B.id -- (Q1)
SELECT A.x, B.y FROM B LEFT OUTER JOIN A ON B.id = A.id -- (Q2)

当我从概念上考虑多重连接时,我通常会很自然地想象将新表作为感兴趣的对象,然后描述其行与之前的行之间的关系。保持条款并行对我没有任何好处,根据我自己的习惯,我通常这样编写连接条件:

SELECT A.x, B.y FROM A LEFT OUTER JOIN B ON B.id = A.id -- (Q3)

我与一位误解了语法如何工作的前同事进行了交谈。对这位同事来说,Q3是错的,Q1是对的。而且我确实认识到,对于旧式外连接语法,这很重要,这很可能是造成这种混乱的根源。我从未听说过或见过其他人使用 ANSI 联接提出这种情况。请回答这个问题并挽回我的声誉,指出我忽略的一些事情,或者对错误的观点提供更深入的见解。

表达式或谓词的顺序对标准 SQL 中的外连接和 ANSI 连接的连接条件有什么不同吗?

4

4 回答 4

5

不,没有区别。

我个人更喜欢你在Q3的风格,我的一些同事更喜欢Q1的风格。我不知道有谁会认为他们中的任何一个是错误的。

查询优化器将查询从里到外变成完全不同的东西,因此谓词在完成后甚至不再作为简单的比较存在。通常它是在索引或表中查找,并且由于只能在一个方向上完成,因此谓词的编写方式没有区别。

我检查了(在 SQL Server 2005 中)两个查询的执行计划,其中谓词操作数的顺序不同,并且正如预期的那样,它们是相同的。

于 2012-07-07T03:21:16.653 回答
3

我也更喜欢 Q3 的 JOIN 条件顺​​序:

... ON B.id = A.id -- (Q3)

由于它直接反映 B.id 是变化更大的一个,因此您可以将 A.id 视为要测试的常数,例如

B.id = 1984

同样,我不想在代码中看到这个......

1984 = B.id

...,像你一样,我不想在查询中看到这个:

A.id = B.id

然而,就像生活中的大多数事情一样,有人喜欢小端,也有人喜欢大端。无论他们选择哪种心智模式,他们都应该至少能够向你解释他们想要的理由A.id = B.id

我想,我必须改变我的偏好,但我的(和你的)首选条件顺序在某些 ORM 中不起作用,特别是在 Linq 中。我还没有理解为什么他们强加条件应该按照 Q1 的顺序:

from x in A
join y in B on x.id equals y.id

并且反转条件(与 Q3 相同,尽管在 SQL 查询中它不是错误)命令导致语法错误,这不会被 Linq 接受:

from x in A
join y in B on y.id equals x.id

现在,我必须找出 Microsoft Linq 设计人员偏爱 Q1 条件顺序的原因。如果它有意义,请尝试欣赏它,即使它(还)没有意义也要接受。


关于:

表达式或谓词的顺序对标准 SQL 中的外连接的连接条件有什么影响吗?

结果方面,没有。在性能方面,我还没有看到联接的条件顺序使查询更快的查询。即使在论坛中,我也没有看到有人支持反转条件以加快查询速度。

如果他们无法向您解释他们首选条件的订单服务的基本原理或心理模型,也许他们只是在做Cargo Cult Programming或更糟的是,Bikeshedding

于 2012-07-07T03:48:47.227 回答
2

相等比较的顺序对连接的结果没有影响。但它可能会因为难以理解的原因影响计算结果的效率。SQL 优化器因受此类看似不重要的细节影响而臭名昭著。

于 2012-07-07T03:04:58.663 回答
1

我更喜欢您的 Q1,但是它对性能绝对没有影响,并且对查询优化器绝对没有影响。

对我来说,在我的扫描过程中,把前面的表格放在第一位可以让我更快地获得相关信息。我可以阅读join table B on A ...并且已经知道哪两个表正在连接在一起。当我阅读时join table B on B.blasdjasdid = ...,我不得不扫描得更远,但仍然不知道最重要的信息,即正在加入哪个表(这是一种命名空间,一个可以理解列名的域)。此外,如果两个表中的列名称相同(在我设计的任何数据库中都是惯用的),我可以避免完全扫描到最后,只读join table B on A.SomethingId ...并且已经知道它是= B.SomethingId.

再深入一点,我鼓励您在workplace.stackexchange.com上询问此事件,因为我怀疑您的服务中断的原因与他们告诉您的不符;对此进行一些调查可能会有所帮助。我并不是说这是你的错,但给出的原因可能是一个借口。

于 2015-12-29T21:14:38.763 回答