2012-01-13 4 views
0

때때로 지금까지는 저장 프로 시저를 사용하여 레코드 세트를 반환하는 기존 ASP 페이지 중 일부에서이 오류가 발생했습니다 (일반적으로 < 2000 행).저장 프로 시저가 ASP 페이지에서 간헐적으로 시간 초과 됨

가 ODBC 드라이버 (0x80040E31)에 대한

Microsoft OLE DB 공급자가 은 [마이크로 소프트] ASP와 그냥 준다 [ODBC SQL Server 드라이버] 제한 시간이 나는 문제없이 실행 서버의 SP를 실행하면

을 만료하지만, 제한 시간이 만료되었습니다.

SP를 다시 컴파일하면 문제가 해결되고 SP는 ASP에서 다시 정상적으로 작동합니다. 하지만 며칠/몇 주 후에 같은 SP/ASP 또는 다른 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

당신이 기술 한 것은 매개 변수 스니핑의 결과로 잘못 캐시 된 쿼리 계획처럼 들린다.

때때로 통계 및 색인이 최신 상태인지 확인하여이를 피할 수 있습니다.

질문에 저장 프로 시저를 게시하는 것이 좋습니다.

정식 참조는 다음과 같습니다

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)) 

이 매개 변수 @Filter 스니핑 매개 변수를 제거하고 평균 선택도를 사용하도록 SQL Server를 알려줍니다 : SQL Server 2008의 Slow in the Application, Fast in SSMS?

는 이후 당신은 OPTIMIZE FOR 사용할 수있다 가치 (통계에 근거).

+0

이 문제가 발생하는 것은 단지 SP가 아니지만 지금까지 게시 한 샘플 코드와 비슷한 문제를 가지고있는 것으로 알고 있습니다. 오늘 밤 나를 위해 잠자리에 드는 링크를 주셔서 감사합니다. :) –

+0

동적 필터가 문제 일 수 있습니다. 필터의 가장 일반적인 형식이 아닌 처음 호출 할 경우 필터의 더 일반적인 값에 대해 더 이상 제대로 작동하지 않는 쿼리 계획을 캐시 할 수 있습니다. 이 기사에서는 가지고있는 옵션에 대해 설명합니다 (SQL 서버 버전에 따라 다름) –

+0

@Mitch는 게임을하고 무슨 일이 일어나는지 살펴볼 것입니다. 우리는 2008 년을 돌면서 손가락을 통과함으로써이 문제를 해결할 것입니다. Muchas Gracias. –

관련 문제