繁体   English   中英

存储过程在特定连接池上超时

[英]Stored procedure timing out on particular connection pool

我有一个存储过程,从我们的网站(通过网站连接池)调用时偶尔会超时。 一旦超时,它总是被锁定到超时,直到使用管理Studio会话中的drop / create或sp_recompile重新编译过程。

虽然超时,但使用Management Studio对同一过程使用相同的参数没有超时。

通过Management Studio执行“更改过程”并且(相当彻底地)更改过程的内部执行并没有清除超时 - 直到运行完整的sp_recompile才会清除。

存储过程以OPTION (RECOMPILE)结束

该过程调用两个函数,这些函数在产品的其余部分中无处不在地使用。 使用这些功能的其他程序(以类似的方式)都可以工作,即使在有关程序超时的期间也是如此。

如果任何人可以提供任何关于可能导致这一时间的进一步建议,将不胜感激。

存储过程如下:

ALTER PROCEDURE [dbo].[sp_g_VentureDealsCountSizeByYear] (
  @DateFrom         AS DATETIME = NULL
  ,@DateTo          AS DATETIME = NULL
  ,@ProductRegion   AS INT = NULL
  ,@PortFirmID      AS INT = NULL
  ,@InvFirmID       AS INT = NULL
  ,@SpecFndID       AS INT = NULL
) AS BEGIN
-- Returns the stats used for Market Overview
DECLARE @IDs    AS IDLIST
INSERT INTO @IDs
    SELECT IDs
    FROM dbo.fn_VentureDealIDs(@DateFrom,@DateTo,@ProductRegion,@PortFirmID,@InvFirmID,@SpecFndID)

CREATE TABLE #DealSizes (VentureID INT, DealYear INT, DealQuarter INT, DealSize_USD DECIMAL(18,2))
INSERT INTO #DealSizes
    SELECT vDSQ.VentureID, vDSQ.DealYear, vDSQ.DealQuarter, vDSQ.DealSize_USD
    FROM dbo.fn_VentureDealsSizeAndQuarter(@IDs) vDSQ

SELECT 
    yrs.Years Heading
    ,COUNT(vDSQ.VentureID)          AS Num_Deals
    ,SUM(vDSQ.DealSize_USD) AS DealSize_USD  
FROM tblYears yrs
    LEFT OUTER JOIN #DealSizes vDSQ ON vDSQ.DealYear = yrs.Years
WHERE (
        ((@DateFrom IS NULL) AND (yrs.Years >= (SELECT MIN(DealYear) FROM #DealSizes))) -- If no minimum year has been passed through, take all years from the first year found to the present.
            OR
        ((@DateFrom IS NOT NULL) AND (yrs.Years >= DATEPART(YEAR,@DateFrom)))   -- If a minimum year has been passed through, take all years from that specified to the present.
    ) AND (
        ((@DateTo IS NULL) AND (yrs.Years <= (SELECT MAX(DealYear) FROM #DealSizes))) -- If no maximum year has been passed through, take all years up to the last year found.
            OR 
        ((@DateTo IS NOT NULL) AND (yrs.Years <= DATEPART(YEAR,@DateTo)))   -- If a maximum year has been passed through, take all years up to that year.
    )
GROUP BY yrs.Years
ORDER BY Heading DESC
OPTION (RECOMPILE)
END

如果你想在每次执行时重新编译SP,你应该用重新编译声明它; 您的语法重新编译最后一个选择:

ALTER PROCEDURE [dbo].[sp_g_VentureDealsCountSizeByYear] (
  @DateFrom         AS DATETIME = NULL
  ,@DateTo          AS DATETIME = NULL
  ,@ProductRegion   AS INT = NULL
  ,@PortFirmID      AS INT = NULL
  ,@InvFirmID       AS INT = NULL
  ,@SpecFndID       AS INT = NULL
) WITH RECOMPILE

我不知道你的程序的哪个部分会导致问题。 您可以尝试注释掉select部分以查看是否从表函数创建临时表会产生性能问题; 如果没有,那么查询本身就是一个问题。 您可以按如下方式重写过滤器:

WHERE (@DateFrom IS NULL OR yrs.Years >= DATEPART(YEAR,@DateFrom))
  AND (@DateTo   IS NULL OR yrs.Years <= DATEPART(YEAR,@DateTo))

或者,或许更好,声明startYear和endYear变量,相应地设置它们并改变这样的地方:

declare @startYear int
set @startYear = isnull (year(@DateFrom), (SELECT MIN(DealYear) FROM #DealSizes))
declare @endYear int
set @endYear = isnull (year(@DateTo), (SELECT MAX(DealYear) FROM #DealSizes))
...
where yrs.Year between @startYear and @endYear

如果WITH RECOMPILE没有解决问题,并且删除最后一个查询也没有帮助,那么您需要检查用于收集数据的表函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM