2011-04-05 4 views
7

모든 것이 물론 상대 경로이지만 단순히 쿼리 관리자를 사용하여 동일한 SQL을 실행하는 것과 비교하면 큰 차이가 있습니다.LINQ 저장 프로 시저 호출 속도가 느림

저는 프로파일 러를 사용하여 LINQ가 저장 프로 시저를 호출 할 때 데이터베이스가 실행하는 SQL 문을 확인했습니다. 결과는 약 1400ms에 반환됩니다. SQL을 복사/붙여 넣기하고 쿼리 관리자를 통해 동일한 SQL을 실행하면 결과가 2ms로 반환됩니다. 이것은 제가해야 할 일이 있는지 궁금하게 생각합니까? 여기에 비슷한 경험을 가진 사람이 있습니까?

다음은 SQL은 LINQ에서 보내는 다음과 같습니다

declare @p26 int 
set @p26=0 
exec sp_executesql N'EXEC @RETURN_VALUE = [dbo].[TapeInfo_Get] @TapeFlag_IsDigitized = @p0, @TapeFlag_ChosenSingleTape = @p1, @TapeFlag_ChosenHierarchy = @p2, @TapeFlag_ChosenForced = @p3, @TapeFlag_ExcludedHierarchy = @p4, @TapeFlag_ExcludedARKBNR = @p5, @TapeFlag_ExcludedForced = @p6, @TapeFlag_ExcludedFilmRoll = @p7, @TapeFlag_ExcludedDVCPRO = @p8, @TapeFlag_ExcludedVHS = @p9, @TapeFlag_ExcludedType = @p10, @TapeFlag_NoticeBNR = @p11, @TapeFlag_NoticeMultiplePNR = @p12, @TapeFlag_NoticeType = @p13, @ProductionFlag_ExcudedDate = @p14, @ProductionFlag_NoticeMultipleTape = @p15, @ProductionFlag_NoticeFilm1C = @p16, @ProductionFlag_NoticeFilmBetaDigial = @p17, @ProductionFlag_ExcludedForeignProd = @p18, @Query = @p19, @PageIndex = @p20, @PageSize = @p21, @ReturnCount = @p22',N'@p0 bit,@p1 bit,@p2 bit,@p3 bit,@p4 bit,@p5 bit,@p6 bit,@p7 bit,@p8 bit,@p9 bit,@p10 bit,@p11 bit,@p12 bit,@p13 bit,@p14 bit,@p15 bit,@p16 bit,@p17 bit,@p18 bit,@p19 varchar(8000),@p20 int,@p21 int,@p22 bit,@RETURN_VALUE int output',@p0=0,@p1=1,@p2=1,@p3=1,@p4=0,@p5=0,@p6=0,@p7=0,@p8=0,@p9=0,@p10=0,@p11=0,@p12=0,@p13=0,@p14=0,@p15=0,@p16=0,@p17=0,@p18=0,@p19=NULL,@p20=0,@p21=10,@p22=0,@[email protected] output 
select @p26 

닷넷 C# 코드는 단순히 :

using(BRSDataContext dc = new BRSDataContext()) 
{ 
    dc.TapeInfo_Get(false, false, false, false, false, false, false, false, false, false, false, null, true, null, false, null, null, null, false, query, startRowIndex, count, false) 
} 

는 내가 부족 뭔가가 있나요? 성능에 큰 영향을 미칠 수있는 아이디어가 있습니까? 데이터베이스 (MSSQL 2008) 및 LINQ를 실행하는 asp.net 사이트를 호스팅하는 웹 서버는 동일한 네트워크에 있으며 Windows server 2008 std 32bit를 실행합니다.

도움 주셔서 감사합니다.

해결 :

SET ARITHABORT ON; 

그래서 그것은 LINQ의 문제는 아니었지만, 일반적인 SQL 서버 문제 더.

+2

먼저 어느 것을 실행 했습니까? SSMS 또는 응용 프로그램? 두 가지 쿼리 방법을 전환 할 때 동일한 성능 결과를 반복적으로 생성 할 수 있습니까? 인용 한 통계를 정확히 어디서 얻고 있습니까? –

+0

@Pete M, 답장을 보내 주셔서 감사합니다. LINQ를 통해 먼저 호출하고 SQL을 쿼리 관리자에 복사 한 다음 실행했습니다. 그러나 첫 번째 호출 이후에도 결과는 LINQ에서 일관되게 느립니다. 측정 값은 SQL Server 2008과 함께 제공되는 프로파일 러에서 가져옵니다. –

+0

Bummer, 실행 계획 문제가되기를 바랐습니다 ... SQL Server에서 1400ms의 실행 시간을 완전히 볼 수 있습니까? 에서 것과 같이, 수송/발표/다른 사람을 포함하지 않기 위하여? LINQPad가 있습니까? DataContext를 참조하고 응용 프로그램의 컨텍스트 외부에서 쿼리를 실행하고 동일한 결과를 얻는 지 확인하십시오. 그것은 완전히 다른 종류의 차이점을 전체적으로 서버 측에서 볼 수 있으며 저장 프로 시저에서 다수의 히트를 일관성있게 유지하는 것은 이상한 일입니다 ... –

답변

8

arithabort를 설정합니다. 단지 그것을 테스트하는 것입니다. 이 문제를 해결하기위한 몇 가지 권장 방법이 있습니다. 하나는 "재 컴파일과 함께"를 저장 프로 시저에 추가하는 것입니다. 하지만 일반적으로 입력 매개 변수를 사용하지 않음으로써 문제를 해결할 직접

예 : 같은

create stored procedure foo(@ParamUserId int) 
as 
    declare @UserId int 
    set @UserId = @ParamUserId 

    select * from Users where UserId = @UserId 

또는 뭔가. 여기

이 문제 여기 http://www.simple-talk.com/sql/t-sql-programming/parameter-sniffing/

+0

감사합니다. 매우 도움이됩니다. –

+1

도움이 될 수있어서 기쁩니다. 하루 종일 내 머리를 긁어 낸 것을 기억합니다. 그때 stackoverflow 알고 좋았을거야 :) – ingo

+0

문제에 대한 광범위한 연구에 큰 링크지만, 거기에 너무 많이 필요가있다) 적어도 그것을 통해 읽고 소화하거나 1 시간 B) 15 또는 20 그것을 훑어보고 문제를 해결하는 데 도움이되는 부분을 찾아보십시오. 나는 후자의 접근법에 갔었지만 sp_recompile을 실행 한 후에도 문제가 다시 발생했다. (위의 링크 작성자가 말한 것 같다). 내 경우, 마침내 내 문제가 해결되었습니다 datetime 매개 변수를 내 sproc에 varchar 매개 변수에 전달했다 (및 sproc 내에서 datetime 변환 한 다음). – Jagd

2

에 좋은 기사가 LINQ가 ARITHABORT 설정하기위한 C#입니다;

System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(myConnectionString); 
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand("set arithabort on;", conn); 
command.Connection.Open(); 
command.ExecuteNonQuery(); 
CMyDataContext myDataContext = new CMyDataContext(conn);