2012-01-13 71 views
0

我們偶爾會發現從使用存儲過程返回記錄集的一些舊的ASP頁面(通常爲< 2000行)出現此錯誤。存儲過程在ASP頁面上間歇性地超時

Microsoft OLE DB提供程序的ODBC驅動程序(0x80040E31) [微軟] [ODBC SQL Server驅動程序]超時過期

當我運行它運行在服務器上的SP沒有問題,但與ASP它只是給出了一個超時過期。

當我重新編譯SP時,它解決了問題,並且SP再次在ASP中正常工作。但是接下來的幾天/幾周後,我從同一個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 

回答

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,並且使用的平均選擇性價值(根據統計)。

+0

這不僅僅是一個SP得到這個問題,但據我所知,那些確實有問題的是類似於我剛剛發佈的示例代碼。感謝您的鏈接...今晚就睡前給我讀:) :) – 2012-01-13 08:05:07

+0

這個動態過濾器可能是問題所在。如果第一次用不是最常見的過濾器形式調用它,則可能會緩存一個查詢計劃,該計劃對於過濾器的更常見的值不再適用。本文描述了您擁有的選項(取決於SQL服務器版本) – 2012-01-13 08:08:41

+0

非常感謝@Mitch將會有一個遊戲並且看看會發生什麼。我們正在運行2008年,所以手指越過這將解決問題。 Muchas Gracias。 – 2012-01-16 02:21:18