在 LINQ 中,Join 和从嵌套查询中选择第一项之间有啥区别

Posted

技术标签:

【中文标题】在 LINQ 中,Join 和从嵌套查询中选择第一项之间有啥区别【英文标题】:In LINQ, what is the difference between Join and selecting the first item from a nested query在 LINQ 中,Join 和从嵌套查询中选择第一项之间有什么区别 【发布时间】:2012-06-27 18:29:07 【问题描述】:

这里有一些 LINQ 用于选择所有订单详细信息。它创建与产品表的连接以获取产品名称:

var query = from od in db.Order_Details
            join p in db.Products on od.ProductID equals p.ProductID
            select new  od.OrderID, od.ProductID, p.ProductName ;

如果我不知道存在 Join,我会这样做:

var query = from od in db.Order_Details
            select new  od.OrderID, 
                         od.ProductID, 
                         ProductName = (from p in db.Products 
                                        where p.ProductID == od.ProductID 
                                        select p.ProductName).First()
            ;

它们生成不同的底层 SQL 代码。第一种方法比第二种方法快吗?如果是,为什么?

预计到达时间:

用于连接查询的db.Log:

SELECT [t0].[OrderID], [t0].[ProductID], [t1].[ProductName]
FROM [dbo].[Order Details] AS [t0]
INNER JOIN [dbo].[Products] AS [t1] ON [t0].[ProductID] = [t1].[ProductID]

第二次查询的db.Log:

SELECT [t0].[OrderID], [t0].[ProductID], (
    SELECT TOP (1) [t1].[ProductName]
    FROM [dbo].[Products] AS [t1]
    WHERE [t1].[ProductID] = [t0].[ProductID]
    ) AS [ProductName]
FROM [dbo].[Order Details] AS [t0]

【问题讨论】:

您的分析器说什么? :) 我不确定分析器是什么,但我会将 db.Log 的输出添加到我的帖子中... 分析器是一种测量代码性能的工具。您的实际性能将取决于许多因素,例如连接字段是否在基础数据存储中建立索引,以及表中有多少数据。 哦,我明白了。我希望这种事情在可以追溯到 pre-linq、纯 sql 时代之前已经被分析了很多次。 您可以获取生成的查询,在启用了“显示执行计划”的 SQL Server Management Studio 中针对您的数据库运行它,以查看哪个性能更高。 【参考方案1】:

连接通常比等效的嵌套选择更快,因为 DBMS 非常擅长优化连接,尽管一个好的 SQL 编译器可能会将它们优化为相同的 SQL。您应该使用使您的目的更明确的那个,在这种情况下可能是 join。

【讨论】:

从问题中发布的 SELECT 语句中可以看出,C# 编译器和 LINQ-to-SQL 都没有执行任何类型的优化 [适用于答案的第一版]。但是,数据库的查询优化器可以轻松处理这种情况,并且可能对两个查询具有相同的性能特征。另一方面,LINQ-to-Objects 没有查询优化器,并且可能会受到这种嵌套查询的影响。【参考方案2】:

您提供的没有连接的第二个示例执行所谓的“相关子查询”,并且通常会比连接慢。结果是相同的,但不同的是获得这些结果的性能。你应该赞成加入。

http://msdn.microsoft.com/en-us/library/ms187638%28v=sql.105%29.aspx

【讨论】:

以上是关于在 LINQ 中,Join 和从嵌套查询中选择第一项之间有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

LINQ to SQL语句之Join

EF Core 嵌套 Linq 选择导致 N + 1 个 SQL 查询

LINQ学习之旅

linq语法大全(转集)

从两个表中选择更新 Linq 查询?

如何通过 join 和 group by 在 C# Linq 中获取 Min?