2013-03-01 5 views
-1

이 분 이상 걸리는 쿼리가
표 2 백만 행
을 가지고 실행해야 가입 [다음 sID]
모두 인덱스가 1보다 작은이있는 PK
[textHash] 색인 할 수있다 널 (null)입니다 내가 원하는 %의 분열
는 [textHash] 이후
두 조건최적화 TSQL은

때문에 다른 조건이에 연합을 구축하는 방법의

가입 널 필요로 할 수있는 곳 기본에 [textHash] 경기 추가되는하기 주요 선택은 옵션이 아닙니다.
다음 주 릴리스에서는 UNION을 사용할 수 있도록 쿼리가 작성되는 방식이 변경되었습니다. 이 null의 경우 일반적으로

좀 어떻게 쿼리 계획 I을 복사하는 내를 알려 주시기 바랍니다 것입니다 경우 PK

Select top 10001 [docFam].[sID] 
From [docSVsys] with (nolock) 
LEFT OUTER JOIN [docSVsys] as [docFam] with (nolock) 
    On [docSVsys].[sID] = [docFam].[sID] 
    Or [docSVsys].[textHash] = [docFam].[textHash] 
Where [docSVsys].[sID] <= '1000' 
Group By [docFam].[sID] 
Order By [docFam].[sID] Asc 

에 따라 행을 포함
를 null이 될 수 속성에 가입하려는 그것을 포함 할 것입니다

해시, 머지 및 루프 힌트를 시도했습니다.
컴파일러가 거부 한 첫 번째 두 개와 LOOP가 더 느리고 힌트가 없습니다.

나는

On ([docSVsys].[textHash] is null and [docSVsys].[sID] = [docFam].[sID]) 
Or [docSVsys].[textHash] = [docFam].[textHash] 

을 시도하고 나는 단지 하나의 조건

가입이 필요하므로 속도가 느린

유사한 쿼리를 2 초
에서 그러나이 경우 [sParID]에서 실행이 null이 있었다

Select top 10001 [docFam].[sID] 
From [docSVsys] with (nolock) 
LEFT OUTER JOIN [docSVsys] as [docFam] with (nolock) 
    On [docSVsys].[sParID] = [docFam].[sParID] 
Where [docSVsys].[sID] <= '1000' 
Group By [docFam].[sID] 
Order By [docFam].[sID] Asc 

작은 수의 행을 반환하는 쿼리의 경우에도 적용됩니다.
이 구문은 위의 구문에 대해 1 초에서 1 분 (1,022 행 반환)으로 실행됩니다.

여전히 많은 행을 반환하는 조건에 대해 두 가지 형식의 쿼리에 문제가 있지만 SQL 또는 구문 문제로 보지 않습니다. 많은 행이 오래 걸릴 것입니다.

Select [docFam].[sID] 
From [docSVsys] with (nolock) 
OUTER APPLY -- cross apply 
    ( 
    Select [docSVsysHashNull].[sID] 
    From [docSVsys] as [docSVsysHashNull]with (nolock) 
    where [docSVsysHashNull].[sID] = [docSVsys].[sID] 
    union 
    Select [docSVsysHashNotNull].[sID] 
    From [docSVsys] as [docSVsysHashNotNull]with (nolock) 
    where [docSVsysHashNotNull].[sID] != [docSVsys].[sID] 
     and [docSVsysHashNotNull].[textHash] = [docSVsys].[textHash] 
) as docFam 
Where [docSVsys].[sID] <= '1000' 
Group By [docFam].[sID] 
Order By [docFam].[sID] Asc 
+0

가 대신 GROUP BY의 DISTINCT를 시도에서 코멘트에 제공되었다? – chrisb

+0

@chrisb DISTINCT는 약간 시간이 걸리고 쿼리 계획의 내용이 동일합니다. – Paparazzi

+0

왜 투표가 늦습니까? – Paparazzi

답변

0

대답처럼 뭔가 @ NikolaMarkovinović

select distinct isnull(docFam.sID, docSVsys.sID) as sID 
from docSVsys 
left join docSVsys as docFam 
    on docSVsys.textHash = docFam.textHash 
where ... 
1

exists 조항으로 작성한 것으로 간주 했습니까? 이

select distinct top 10001 a.[sID] 
From [docSVsys] as a 
where exists 
(
select * 
From [docSVsys] as b 
where b.[sID]<='1000' 
and (a.[sID] = b.[sID] OR a.[textHash] = b.[textHash]) 
) 
+0

보다 2 배 빠릅니다. 쿼리를 반환하는 쿼리는 그다지 빠르지 않고 반환 조건이 느린 것은 아닙니다. 여전히 +1 할 가치가있었습니다. – Paparazzi