为什么此查询超时?

时间:2010-07-28 07:39:51

标签: linq-to-sql performance

我有一个带有多个连接的L2S查询,它应该在大约3秒内返回11条记录。但是,它会在30秒后超时,除非我指定Take参数(我使用Take(20),即使它只返回11条记录),在这种情况下,它会在3个预期的时间范围内返回11条记录。

查询如下所示:

(from q in TransmittalDetails where q.TransmittalHeader.TransmittalEntityID == 196
      && q.TransmittalHeader.DateRangeBeginTimeID == 20100101
      && q.TransmittalHeader.ScenarioID == 2
      && q.LineItem.AccountType.AccountCategory.AccountGroup.
             AccountSummary.AccountSummaryID == 6
 select new {
q.LineItem.AccountType.AccountCategory.AccountGroup.AccountGroupID,
q.LineItem.AccountType.AccountCategory.AccountGroup.AccountGroup1
   }).Distinct()

这会生成一些如下所示的SQL:

DECLARE @p0 Int = 196
DECLARE @p1 Int = 20100101
DECLARE @p2 Int = 2
DECLARE @p3 Int = 6

SELECT DISTINCT [t5].[AccountGroupID], [t5].[AccountGroup] AS [AccountGroup1]
FROM [dbo].[TransmittalDetail] AS [t0]
INNER JOIN [dbo].[TransmittalHeader] AS [t1] ON [t1].[TransmittalHeaderID] = 
   [t0].[TransmittalHeaderID]
INNER JOIN [dbo].[LineItem] AS [t2] ON [t2].[LineItemID] = [t0].[LineItemID]
LEFT OUTER JOIN [dbo].[AccountType] AS [t3] ON [t3].[AccountTypeID] = 
   [t2].[AccountTypeID]
LEFT OUTER JOIN [dbo].[AccountCategory] AS [t4] ON [t4].[AccountCategoryID] = 
   [t3].[AccountCategoryID]
LEFT OUTER JOIN [dbo].[AccountGroup] AS [t5] ON [t5].[AccountGroupID] = 
   [t4].[AccountGroupID]
LEFT OUTER JOIN [dbo].[AccountSummary] AS [t6] ON [t6].[AccountSummaryID] = 
   [t5].[AccountSummaryID]
WHERE ([t1].[TransmittalEntityID] = @p0) AND ([t1].[DateRangeBeginTimeID] = @p1) 
   AND ([t1].[ScenarioID] = @p2) AND ([t6].[AccountSummaryID] = @p3)

现在,真正奇怪的是,如果我在Management Studio中执行该SQL,它会在3秒内返回11行,但生成它的linq查询将在30秒的活动后超时。

指定Take参数没有多大意义。我打错了吗?

注意:代码超时而没有Take()参数,无论我是从我的应用程序还是Linqpad执行它。同样,在app和linqpad中,它与Take()参数一起工作正常。此外,如果没有它,它只返回19行。

1 个答案:

答案 0 :(得分:1)

使用和不使用.Take(前n个)比较查询的执行计划。你可能第一次得到了一个糟糕的查询执行计划,并添加了Take只是更改了查询以便再次编译。

使用sp_recompile或dbcc freeproccache删除执行计划,看看是否有所作为。

您还可以使用a profiler来提取有关查询成本,执行计划等的更多信息......