存储过程在ASP页面上间歇性地超时

时间:2012-01-13 07:25:49

标签: sql sql-server-2008 asp-classic

我们偶尔会从一些使用存储过程返回记录集的旧ASP页面中得到此错误(通常< 2000行)。

Microsoft OLE DB Provider for ODBC Drivers(0x80040E31) [Microsoft] [ODBC SQL Server驱动程序]超时已过期

当我在服务器上运行SP时,它运行时没有问题但是使用ASP只会使Timeout过期。

当我重新编译SP时,它修复了问题,SP再次在ASP中运行良好。但是之后的几天/几周后,我从同一个SP / ASP或其他人那里得到同样的问题。源表和ASP根本没有改变。

让我难过。

示例SP:

USE [DB-Name]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[MY_StoredProcedure]
    @Filter varchar(50) = null,
    @SortOrder bit = 1,
    @SortField varchar(50) = 'MyCol1',
    @Page int = 1,
    @RecordsPerPage int = 20
AS
BEGIN
    SET NOCOUNT ON
    CREATE TABLE #TempTable(RowID int IDENTITY,Col1 int,Col2 varchar(20),Col3 datetime)
    INSERT INTO #TempTable
    SELECT Col1, Col2, Col3 FROM [DB-Table]
    WHERE 
        @Filter is null OR (
            Col1 LIKE '%' + @Filter + '%'
            OR Col2 LIKE '%' + @Filter + '%'
            OR Col3 LIKE '%' + @Filter + '%'
        )       
    ORDER By
        CASE WHEN @SortField = 'MyCol1' AND @SortOrder = 1 THEN Col1 END ASC,
        CASE WHEN @SortField = 'MyCol1' AND @SortOrder = 0 THEN Col1 END DESC,
        CASE WHEN @SortField = 'MyCol2' AND @SortOrder = 0 THEN Col2 END DESC,
        CASE WHEN @SortField = 'MYCol2' AND @SortOrder = 1 THEN Col2 END ASC,
        CASE WHEN @SortField = 'MyCol3' AND @SortOrder = 1 THEN Col3 END ASC,
        CASE WHEN @SortField = 'MyCol4' AND @SortOrder = 0 THEN Col3 END DESC

    -- Find out the first and last record we want
    DECLARE @FirstRec int, @LastRec int
    SELECT @FirstRec = (@Page - 1) * @RecordsPerPage
    SELECT @LastRec = (@Page * @RecordsPerPage + 1)

    -- Now, return the set of paged records, plus, an indiciation of if we have more     records or not!
    SELECT *,TotalRecords=(SELECT COUNT(RowID) FROM #TempTable),MoreRecords=(SELECT     COUNT(RowID) FROM #TempTable TI WHERE TI.RowID >= @LastRec)
    FROM #TempTable
    WHERE 
         RowID > @FirstRec AND RowID < @LastRec

    DROP TABLE #TempTable
    -- Turn NOCOUNT back OFF
    SET NOCOUNT OFF
END
GO

1 个答案:

答案 0 :(得分:3)

您所描述的内容听起来像是参数嗅探导致的错误缓存的查询计划。

有时可以通过确保您的统计信息和索引是最新的来避免。

建议您发布有问题的存储过程。

规范参考是:Slow in the Application, Fast in SSMS?

在SQL Server 2008及更高版本中,您可以使用OPTIMIZE FOR

SELECT Col1, Col2, Col3 FROM [DB-Table] 
WHERE  
    @Filter is null OR ( 
        Col1 LIKE '%' + @Filter + '%' 
        OR Col2 LIKE '%' + @Filter + '%' 
        OR Col3 LIKE '%' + @Filter + '%' 
    )        
ORDER By 
    CASE WHEN @SortField = 'MyCol1' AND @SortOrder = 1 THEN Col1 END ASC, 
    CASE WHEN @SortField = 'MyCol1' AND @SortOrder = 0 THEN Col1 END DESC, 
    CASE WHEN @SortField = 'MyCol2' AND @SortOrder = 0 THEN Col2 END DESC, 
    CASE WHEN @SortField = 'MYCol2' AND @SortOrder = 1 THEN Col2 END ASC, 
    CASE WHEN @SortField = 'MyCol3' AND @SortOrder = 1 THEN Col3 END ASC, 
    CASE WHEN @SortField = 'MyCol4' AND @SortOrder = 0 THEN Col3 END DESC 
OPTION (OPTIMIZE FOR (@Filter UNKNOWN))

这告诉SQL Server消除参数@Filter的参数嗅探,并使用平均选择性值(基于统计信息)。