2010-01-22 2 views
1

내가 가진 큰 쿼리의 영역이 성능 문제를 일으키는 지 확인하기 위해 나는 세 단계를 수행했습니다. 실행 계획을 포함하여 시간 통계를 켜기로 설정하고 문제가 발생할 수 있다고 생각되는 섹션 바로 앞이나 뒤에 인쇄하십시오. 예 :시간 통계, 실행 계획 및 "인쇄"에 대한 질문

print '1' 
SELECT ID FROM Test 
print '2' 

내 실행 계획을 보면 특정 섹션이 "비용"의 많은 부분을 차지하고 있다고합니다. 이 백분율을 내 print '1'print '2' 사이의 경과 시간과 비교해 보면 백분율이 거의 맞지 않는 것처럼 보입니다.

예상 비용보다 인쇄 된 값과 시간 통계를 신뢰할 수 있습니까? 그렇다면 예상 비용보다 인쇄 된 값 사이의 경과 시간이 긴 영역에 초점을 맞추는 것이 합당한가요?

+0

당신이 이야기하고있는 * 추정 * 계획 또는 * 실제 * 계획에 대해 :

는 다음과 같이 무엇에 내가 자주 할 수있다? 예. SSMS 작업 표시 줄 버튼 '예상 실행 계획 표시'또는 '실제 실행 계획 포함'작업 표시 줄 버튼이 켜지면 쿼리 실행 후 표시된 계획이 표시됩니다. –

+0

나는 실제 실행 계획에 대해 말하고 있지만 "예상 운영자 비용"이라고 여전히 말합니다. –

답변

1

'1'만 인쇄하고 '2'를 인쇄하면 SSMS 메시지 창에 메시지가 표시 될 때까지의 시간을 측정 한 다음 서버와 클라이언트 간의 출력 버퍼링의 피해가 줄어 듭니다. print '1' 일 수 있으며 클라이언트에 즉시 반환되지 않으며 SqlClient, ADO.Net 및 SSMS는 자체 버퍼링을 일부 수행합니다. 따라서 전체적으로 SSMS 결과 메시지 패널에서 '1'을 실제로 볼 수있는 것보다 나중에 표시 할 수 있습니다. '1'뿐만 아니라 getdate()에서 시간을 인쇄하는 것이 훨씬 더 좋습니다. 이렇게 방정식에서 버퍼링을 제거하면 출력이 SSMS에 의해 표시된 시간이 아니라 서버가 '인쇄'를 실행 한 시간을 메시지 자체에서 볼 수 있습니다.

SET STATISTICS TIME ON은 항상 더 정확하지만 때로는 어떤 진술을 언급 하는지를 이해하기 어렵습니다.

declare @nowString varchar(100); 
declare @start datetime, @end datetime, @rc int, @elapsed int; 

set @start = getdate(); 

select many, fields 
from bigtable 
join manytables on condition = complex 
where matches = many 
order by wacky sort; 

set @rc = @@rowcount; 
set @end = getdate(); 
set @elapsed = datediff(ms, @start, @end); 
set @nowString = cast(varchar(100), getdate(), 14); 
raiserror(N'%s: At select No 1. Selected %i rows in %i ms', 10, 1, %nowString, @rc, @elapsed); 

set @start = getdate(); 
...next select here... 
1

PRINT 문이 출력용으로 버퍼링되기 때문에 안전하지 않습니다. 즉각적인 것은 아닙니다. 실행 계획은 가장 비용이 많이 드는 부분을 식별하고 누락 된 색인 (예 : 테이블 스캔이있는 경우)을 식별하는 데 도움이되므로 성능 문제를 찾는 데 적합합니다.

또한 정말 SQL Profiler 사용해야합니다 - SQL:StmtStartingSQL:StmtCompleted 이벤트를 모니터링 - 당신에게 각 문장 실행하는 데 걸리는 시간에 대한 통계 (StmtCompleted 당신이 관심있는 주이다) 보여줄 것이다.

+0

예 처음에 실행 계획을 사용했고 인덱스를 찾는 모든 것을 얻었지만 여전히 긴 실행 계획을보고 있습니다. 나는 프로파일 러가 말하는 것을 보게 될 것이다. –