Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 特定连接池上的存储过程超时_Sql_Stored Procedures_Timeout - Fatal编程技术网

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

Sql 特定连接池上的存储过程超时,sql,stored-procedures,timeout,Sql,Stored Procedures,Timeout,我有一个存储过程,当通过网站连接池从我们的网站调用时,它偶尔会超时。一旦超时,它将始终锁定在超时状态,直到使用Management Studio会话中的drop/create或sp_recompile重新编译该过程 虽然正在超时,但对于使用ManagementStudio的相同过程,使用相同的参数不会超时 通过ManagementStudio执行ALTER过程并相当大幅度地更改过程的内部执行并没有清除超时-在运行完整的sp_重新编译之前不会清除超时 存储过程以“重新编译”选项结束 该过程调用两个

我有一个存储过程,当通过网站连接池从我们的网站调用时,它偶尔会超时。一旦超时,它将始终锁定在超时状态,直到使用Management Studio会话中的drop/create或sp_recompile重新编译该过程

虽然正在超时,但对于使用ManagementStudio的相同过程,使用相同的参数不会超时

通过ManagementStudio执行ALTER过程并相当大幅度地更改过程的内部执行并没有清除超时-在运行完整的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
) 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))

如果使用“重新编译”无法解决问题,并且删除最后一个查询也没有帮助,则需要检查用于收集数据的表函数

尝试在临时表上使用索引。。这将提高性能。谢谢你的评论。在这种情况下,我怀疑它是否会提高性能,因为返回的行不到1000行。是的,当然。。。。我已经实时应用了…太好了,谢谢你,尼古拉。我会按顺序试一试。当然,困难在于我不知道如何重现错误,因此测试非常费劲——除非它再次超时,否则我永远无法确定它是否已被解决,在这种情况下,我知道它没有被解决。理想情况下,我不希望每次都要重新编译,但如果它解决了问题,那么老实说,这就足够了,因为这是一个相对较低优先级的开发问题。@Millsy先生在重新阅读所有内容后,我想我会从dbo.fn_venturedalids开始。这可能是因为。是的,我一开始确实看了那里——事实上,我有一个关于这个的问题很久以前就有了:在。这个函数是这个应用程序的绝对骨架,但是应用程序上的其他任何地方都没有受到轻微的影响。顺便说一下,我现在已经在存储过程中添加了正确的重新编译方法。我会定期测试它,如果一周后它仍然没有超时,我会回来把它标记为答案。我很满意这个程序现在正在运行。通过重新编译创建存储过程就足够了,谢谢。
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