代码之家  ›  专栏  ›  技术社区  ›  Erik Funkenbusch

为什么查询超时?

  •  0
  • Erik Funkenbusch  · 技术社区  · 15 年前

    我有一个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)
    

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

    指定take参数没有多大意义。我是不是碰到了虫子?

    注意:无论是从应用程序还是linqpad执行take()参数,代码都会超时。同样,在app和linqpad中,它可以通过take()参数正常工作。另外,如果没有distinct,它只返回19行。

    1 回复  |  直到 15 年前
        1
  •  1
  •   KristoferA    15 年前

    比较带有和不带有.take的查询的执行计划(前n个)。您可能第一次得到了一个错误的查询执行计划,添加take只是更改了查询,所以它被再次编译。

    使用sp_recompile或dbcc freeproccache删除执行计划,看看这是否会有所不同。

    您也可以使用 a profiler 提取有关查询成本、执行计划等的更多信息…