2017-03-28 23 views
1

Microsoft SQL Server에서 느리게 실행되는 쿼리가 있습니다. 매우 느린 https://www.brentozar.com/pastetheplan/?id=BJUrHRwngMS SQL Server 실제 작업 당 실제 CPU 비용

쿼리됩니다 : 다음은 쿼리 및 실행 계획이다

Table 'Worktable'. Scan count 30, logical reads 184041, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'SiteVersions'. Scan count 1, logical reads 363, physical reads 0, read-ahead reads 351, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table '#BB50937F'. Scan count 1, logical reads 5979, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'AllWebs'. Scan count 11, logical reads 3041, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'AllSites'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

(1 row(s) affected) 

SQL Server Execution Times: 
    CPU time = 715296 ms, elapsed time = 873728 ms. 
SQL Server parse and compile time: 
    CPU time = 0 ms, elapsed time = 0 ms. 

이 이중 인텔 (R) 제온 (R) CPU에 2.70GHz @ E5-2680 0, 2700 MHz의 , 8 코어, 16 논리 프로세서 시스템. 쿼리는 max-dop가 1로 실행됩니다.

실제 실행 계획은 특정 정렬 연산이 가장 큰 예상 비용을 갖고 매우 많은 수의 행을 반환하는 연산이 없음을 나타냅니다.

그러나 실제 실행 계획을 살펴보면 정렬 작업으로 인해 CPU가 모두로드되는 경우는 거의 없습니다. 예를 들어 별도의 독립 실행 형 쿼리에서 정렬 작업을 실행하면 매우 빠릅니다.

성능 킬러가되는 병합 조인이 의심 스럽습니다. 두 개의 평균적으로 큰 행 집합 (29840 및 9557 행, resp)을 조인하므로 매우 많은 수의 조인 된 행이 생성 될 수 있습니다. 그것은 매우 제한적이지 않은 WHERE 절과 각각의 잔여 행에 대해 평가되어야하는 몇 가지 함수가있는 비싼 RESIDUAL 연산을가집니다. 그러나 나는 실제 숫자로 내 의혹을지지 할 수 없다.

  • SQL 서버에서 물리적 작업 당보고 된 실제 CPU 비용을 얻을 수있는 방법이 있나요 :

    따라서, 나는 나의 의심을 확인할 수 있도록 몇 가지 질문이?

  • 실행 된 RESIDUAL 작업의 실제 개수 및/또는 병합 조인 작업에서 WHERE 절 뒤에 남아있는 행 수에 대해보고하는 방법이 있습니까?
  • 'Worktable'에서 논리적 읽기가보고 된 184041과 관련된 CPU 비용을 계산하는 방법이 있습니까?
  • 물리적 작업이 '작업대'

감사를 사용하여 찾을 수있는 방법이 있나요,

+0

[이 링크] (https://www.brentozar.com/pastetheplan/)는 실행 계획을 공유하는 데 도움이 될 수 있습니다. – DavidG

+0

'OPTION (RECOMPILE)'을 추가해보십시오. 옵티마이 저가 테이블 변수에 대한 통계를 유지하지 않으므로 행을 1 행만 있다고 가정합니다. 실제로 30,000 개의 행이 있으며 전체 행 견적을 상당히 왜곡합니다. 'RECOMPILE'은 최소한 (이것은 문서화되어 있지 않지만 실제로는) 수정되었다. 대신 임시 테이블을 사용합니다. –

+0

링크 @DavidG를 주셔서 감사합니다. 질문을 편집하고 링크를 사용하여 실행 계획 공유를 개선했습니다. –

답변

0

난 당신이보고있는 CPU 비용에 대한 걱정을 너무 많이하지 않을, 그들은 단지입니다 비트 표시기를 사용하면 CPU가 쿼리에서 얼마나 많은 압력을 받고 있는지 알 수 있습니다. 이 경우에는 CPU 비용이 subquery의 rank() 및 where 절의 함수와 함께 쿼리의 복잡성 때문에 발생한다고 생각합니다.

내가 시도하고 최적의 계획을 쿼리 최적화 그림을 도울하고 중간 결과 일이다 개선하기 위해, 몇 가지 논리적 인 부분에서 쿼리를 분할 할 :

select SiteId 
      , WebId 
      , VersionId 
      , Version 
      , rank() over (partition by SiteId, WebId, VersionId order by Id desc) as Rank 
    into #tempSiteVersions 
    from SiteVersions; 

    with cteFirstRankingSites as 
    (
     select SV.SiteId 
       , S.PlatformVersion 
       , SV.Version 
       , SSV.ApplicableWebTemplate 
       , W.WebTemplate 
       , SSV.PreviousTargetVersionNumber 
       , SSV.TargetVersionNumber 
     from #tempSiteVersions as SV 
       join TVF_Webs_NoLock_ALL() as W on W.SiteId = SV.SiteId 
       join Sites as S with (nolock) on W.SiteId = S.Id 
       join @SiteSequenceVersions as SSV on SV.VersionId = SSV.Id 
     where SV.Rank = 1 
    ) 
    select distinct 
      SiteId 
    from [cteFirstRankingSites] as frs 
    where (
      (
       (dbo.fn_ConvertVersionToNumber(frs.PlatformVersion) < 15000000000000) 
       and (dbo.fn_ConvertVersionToNumber(frs.Version) < frs.PreviousTargetVersionNumber) 
      ) 
      or (
       (dbo.fn_ConvertVersionToNumber(frs.PlatformVersion) >= 15000000000000) 
       and (dbo.fn_ConvertVersionToNumber(frs.Version) < frs.TargetVersionNumber) 
       ) 
      ) 
      and (
       frs.ApplicableWebTemplate = 0 
       or frs.ApplicableWebTemplate = frs.WebTemplate 
       ) 

가있을 수 있습니다 거기에 구문 오류가 있기 때문에 나는 실제 테이블과 함께 작동하지만, 당신은 아이디어를 얻을 필요가 없습니다.

+0

답장을 보내 주셔서 감사합니다. 나는 당신의 제안을 시도했다. (구문은 100 % 정확했다!). 불행히도 성능은 여전히 ​​매우 나쁩니다. 또한 Microsoft SharePoint에서 자동 생성 된 쿼리이기 때문에 실제 작업 부하에서 쿼리를 편집 할 수 없습니다. 또한 쿼리 최적화 방법이 아니라 물리적 병합 조인 작업과 관련된 실제 CPU 비용을 결정하는 방법에 대해 궁금했습니다. 그 질문에 대한 답을 갖고 있습니까? –

+0

개별 작업에 대한 실제 CPU 비용을 지원할 수 없으며 다른 사람이이를 결정할 수있는 방법이있을 수 있습니다. 내가 아는 한, 예상 비용은 옵티 마이저가 가장 효율적인 사용 계획을 결정하는 데 사용됩니다. 따라서 왜 내가 쿼리를 변경하는 것이 좋습니다. –

+0

또한 병합 연산자가 문제가 아닌 것으로 보입니다. RANK() 함수를 사용하여 전체 테이블을 정렬하고 클러스터 된 인덱스 (테이블) 검색 및 높은 전체 비용으로 정렬 작업을 일으키고 있습니다.쿼리 계획의 두 작업은 전체 실행의 84 %를 차지합니다. 정렬 작업을 호출 할 때 rank()를 적용하는 것보다 우선 순위가 필요한 데이터를 제한하십시오. –

0

SQL Server에서 실제 작업 당보고 된 실제 CPU 비용을 구할 수있는 방법이 있습니까?

당신은 설정 통계는 별도로 각각의 논리 연산자를보고 그렇지 않으면 당신이 바로 비용을

옵션 1 볼 논리 연산자를 클릭하면, 아래와 같이에 프로필을 사용할 수 있습니다

설정 통계 프로필
쿼리

옵션 2 :
마우스 오른쪽 버튼으로 클릭하고 노드 속성을 참조
enter image description here

옵션 3 :
2016 SP1에서 적용 , 당신은 DMV 아래에 사용할 수 있지만 쿼리

당신이 추적 할 수있는이 방법 전에 set statistics profile를 추가해야 라이브 통계 및 더 많은 정보를 원하시면

select 
session_id,physical_operator_name, 
row_count,actual_read_row_count,estimate_row_count,estimated_read_row_count, 
rebind_count, 
rewind_count, 
scan_count, 
logical_read_count, 
physical_read_count, 
logical_read_count 
from 
sys.dm_exec_query_profiles 
where session_id=55; 

는 실제 한 접점에보고 할 수있는 방법이 있나요 실행 된 RESIDUAL 연산의 r 및/또는 병합 조인 연산에서 WHERE 절 뒤에 남아있는 행 수?

이 SQLServer에 구현되어 있지만,이 표시를 들어, 2016 SSMS 및 SQL2012의 SP3 이상 버전에 있어야합니다, (내가 2016 SP1 오전, 나는 2014 확실하지, 볼 수 있습니다) 내 컴퓨터에서 화면 아래 .See ..

enter image description here

은 '작업대'에 읽어 논리보고 된 184,041과 관련된 CPU 비용을 추정 할 수있는 방법이 있습니까?

작업대 그래서 실제 작업은 '작업대'

를 사용하여 찾을 수있는 방법이 있나요 당신에게 운영자

의 비용을 줄 것이다 연산자를 추적, 운영자와 연결됩니다

대부분 운영자가 귀하의 경우 .IN 작업 테이블을 사용하여 정렬, 그것은 고정 t에

몇몇 권고 종류의 경고와 연산자 그는 쿼리 :

1.) 나는 73 %의 비용을 가지고있는 쿼리에 의해 파티션에서 정렬 연산자를 참조하십시오, 그래서 나는 아래의 인덱스를 사용하여 정렬을 제거하는 것이 좋습니다. 테이블이 큰 경우 SQL 잘 통계

2를 가질 수 있도록이 지수는 만 또한 내가 파생 테이블에 위의 출력을 삽입하는 것이 좋습니다이 쿼리

create index nci_somename on siteversions 
(siteid,webid,versionid,id desc) 
include(version) 

에 대해 적용됩니다.) 모든 당신의 술어는 술어의 그 유형에서 모든 스 SARGable되지 않습니다

dbo.fn_ConvertVersionToNumber(S.PlatformVersion) < 15000000000000) 

이하 같다) 열이 통계는 해당 테이블에 대한 통계를 업데이트하거나 수동으로

3. 하나를 만들어보십시오, 경고 표시 웨브. 다시 작성하십시오.

+0

정교한 답변에 감사드립니다. 실제 CPU 비용을 반환하기 위해 사용자가 제공하는 옵션에 관해서는 실제 CPU 비용이 아닌 실제 행과 실행 시간 만 반환한다고 말할 수있는 한. 그리고보고 된 CPU 비용은 쿼리가 실제로 실행되기 전에 쿼리 최적화 프로그램에서 사용 된 예상 비용입니다. 또는보고 된 가치의 의미를 잘못 이해하고 있습니까? 'Worktable'에 대한 팁을 주셔서 감사합니다. –

+0

나는 생각한다 **, 그 값들도 추정 된 CPU 비용을 말하는데, 그것들은 당신이 얻을 수있는 가장 가까운 값일 수있다. – TheGameiswar

+0

견적은 내가 찾을 수 있었던 유일한 값이고, 따라서 나의 원래의 질문이다. 그래서 당신이 옳을 수도 있습니다. 이 경우 CPU로드가 (함수의 반복 호출) (쿼리 최적화 프로그램이 의심 할 여지없이 CPU 비용이 0 인 것으로 추정 됨) 발생했는지 확인할 수있는 직접적인 방법은 없습니다. –