"where"和"join"有什么区别?(这是一个关于IT技术的问题)

11

什么是区别?

var q_nojoin = from o in one
               from t in two
               where o.SomeProperty == t.SomeProperty
               select new { o, t };

并且

var q_join = from o in one
             join t in two on o.SomeProperty equals t.SomeProperty
             select new { o, t };

它们似乎给我相同的结果。


1
这与SQL的隐式连接和显式连接相同。两者都是连接,但第二个是显式的。 - spender
这是“适合你的任何方式” - 哈,看到我做了什么吗? - PostMan
5个回答

14

它们可以得到相同的结果,但使用联接可以更快,除非您使用LINQ to SQL,这样数据库就能够优化查询。

我进行了一个测试,其中有两个包含5000个项目的数组,使用联接的查询比不使用联接的查询快约450倍(!)。

如果您使用LINQ to SQL,数据库将优化这两个查询以执行相同的任务,因此在这种情况下性能没有差异。然而,显式的联接被认为更易读。

如果您使用LINQ对不同的数据源进行操作,则没有优化层,因此查询的工作方式存在显著差异。联接使用哈希表或类似方法快速查找匹配值,而不使用联接的查询将比较一个表中的所有项目与另一个表中的每个项目。联接的复杂度大致为O(n+m),而没有联接的查询的复杂度为O(n*m)。这不仅意味着不使用联接的查询速度较慢,而且随着数据增长,它的效率会呈指数级下降。


1

JOIN 是通过使用每个表中共有的值来组合两个(或多个)表中的字段的一种方法。

WHERE 子句指定 SQL(数据操作语言)语句只应影响符合指定条件的行(将 WHERE 子句视为过滤器)。


完全没有回答我的问题 :( - Difference Engine
啊,LINQ 查询的语义(关于 WHERE 和 JOIN)与 ANSI SQL 查询的语义有所不同吗? - Joubert Nel
即使在SQL查询中,这也不能回答问题。你说“JOIN是一种将两个表的字段组合起来的方法”,但是from a, b where a.Field=b.Field也是如此,所以它并没有回答问题,即它们之间的区别是什么。 - Timwi
@timwi 当然,连接(显式或隐式)可以包含 WHERE 子句(作为过滤器的 WHERE 子句)。也许我应该针对具体的示例进行说明,而不是解释连接和 WHERE 子句之间的概念差异。 - Joubert Nel
SQL的一个重要区别在于其清晰度——例如,在使用JOIN语法时,更容易检测到不完整的连接条件,从而避免笛卡尔积的产生。它有助于区分连接条件和过滤/限制条件。 - Adam Musch

0

实际上,根据许多其他因素,您可以通过使用其中之一来获得性能提升。我想象(尽管我没有事实依据)连接比WHERE子句更可搜索。

编辑:结果证明我完全错了。这两种类型之间的性能没有区别。然而,新的样式(使用JOIN)更容易阅读(在我看来),并且微软已经表示他们不会无限期地支持旧样式(使用WHERE的外部连接)。


0
实际上,在 SQL 中,join-on 语句可以写在 from-where 语句中(如果你真的想要)。但是你知道,在 SQL 语句中我们有 left joinleft outer join 等等,这使得我们更容易表达我们想要的内容(当然你也可以使用 from-where,但这会让你的代码看起来很疯狂)。因此,如果我们想要过滤结果,我们总是使用 where,而如果表之间存在关系,则使用 join

0

第一个查询实际上是在说:“对这些集合执行交叉连接(创建一个NxM矩阵),然后只取沿对角线的那些,并将它们给我”

第二个查询实际上是在说:“创建一个仅包含属性匹配项的列表”。

结果是相同的,但到达目的地的过程有点不同。

由于SQL数据库通常高度优化,因此当您请求第一个时,服务器会直接说“白痴用户...”,并替换为第二个。

在非SQL环境(如Linq-to-Objects)中,如果您要求第一个,则会执行该操作,并且您将看到显着的性能损失。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接