为什么Linq2SQL生成嵌套查询而不是使用JOIN?

时间:2012-03-12 11:36:13

标签: sql-server-2008 linq-to-sql

我试图理解为什么Linq正在为下面的语句生成SQL:

var dlo = new DataLoadOptions();
dlo.LoadWith<TemplateNode>(x => x.TemplateElement);
db.LoadOptions = dlo;

var data = from node in db.TemplateNodes
           where node.TemplateId == someValue
           orderby node.Left
           select node;

生成以下SQL:

SELECT [t2].[Id],
       [t2].[ParentId],
       [t2].[TemplateId],
       [t2].[ElementId],
       [t2].[Left]  AS [Left],
       [t2].[Right] AS [Right],
       [t2].[Id2],
       [t2].[Content]
FROM   (SELECT ROW_NUMBER() OVER (ORDER BY [t0].[Left]) AS [ROW_NUMBER],
               [t0].[Id],
               [t0].[ParentId],
               [t0].[TemplateId],
               [t0].[ElementId],
               [t0].[Left],
               [t0].[Right],
               [t1].[Id]                                AS [Id2],
               [t1].[Content]
        FROM   [dbo].[TemplateNode] AS [t0]
               INNER JOIN [dbo].[TemplateElement] AS [t1]
                 ON [t1].[Id] = [t0].[ElementId]
        WHERE  [t0].[TemplateId] = 16 /* @p0 */) AS [t2]
WHERE  [t2].[ROW_NUMBER] > 1 /* @p1 */
ORDER  BY [t2].[ROW_NUMBER]

TemplateNode.ElementIdTemplateElement.Id有一个外键。

我原本希望查询生成JOIN,如下所示:

SELECT * FROM TemplateNode
INNER JOIN TemplateElement ON TemplateNode.ElementId = TemplateElement.Id
WHERE TemplateNode.TemplateId = @TemplateId

根据the answers to this question中的建议,我已经分析了两个查询,并且JOIN比嵌套查询快3倍。

我正在使用.NET 4.0 Windows窗体应用程序来测试SQL Server 2008 SP2 64位开发人员版。

2 个答案:

答案 0 :(得分:1)

LINQ-SQL生成ROW_NUMBER查询的唯一原因是Skip方法。就像上面的SQL似乎有点奇怪,我认为在T-SQL中没有像MySQL的Limit 10,25这样的简单分页的构造,所以在使用SkipTake时你得到上面的SQL。 / p>

我认为有Skip用于分页目的,而LINQ-SQL正在修改查询。如果您使用LINQ-Pad之类的应用程序,则可以运行不同的LINQ查询以查看其生成的SQL。

答案 1 :(得分:0)

您的加入示例并不等效。你不能得到ROW_NUMBER,然后只选择WHERE ROW_NUMBER&gt;行。 1简单连接。您必须进行子选择或类似操作才能获得此结果。