2015-01-13 3 views
0

다음 쿼리는 매우 느리게 실행되며 예상 된 실행 계획을 사용하여 문제를 최종 INNER JOIN의 조건으로 좁혔습니다.INNER JOIN 또는 조건에 대한 쿼리 최적화

SELECT 
    TableE.id 
FROM 
    TableA WITH (NOLOCK) 
    INNER JOIN TableB WITH (NOLOCK) 
     ON TableA.[bid] = TableB.[id] 
    LEFT JOIN TableC WITH (NOLOCK) 
     ON TableB.[cid] = TableC.[id] 
    LEFT JOIN TableD WITH (NOLOCK) 
     ON TableA.[did] = TableD.[id] 
    INNER JOIN TableE WITH (NOLOCK) 
     ON TableD.[eid] = TableE.[id] 
      OR TableE.[numericCol] = TableB.[numericCol] -- commenting out this OR statement leads to large performance increase 
WHERE 
    TableA.[id] = @Id 

나는이 TableB의에서 다음 인덱스 :

CREATE NONCLUSTERED INDEX [IX_TableE_numericCol] ON [dbo].[TableE] 
(
    [numericCol] ASC 
) 

어떤 아이디어 :

CREATE UNIQUE NONCLUSTERED INDEX [IX_TableB_numericCol_id] ON [dbo].[TableB] 
(
    [numericCol] ASC, 
    [id] ASC 
) 

및 TableE에

?

+0

이 쿼리는 프로 시저에 있습니까? 그렇다면 매개 변수 스니핑을 살펴볼 수 있습니다. – Mihai

+0

'TableB. [numericCol]'에 대한 색인이 있습니까? – Mihai

+0

데이터 누락 및/또는 중복으로 멋지다면 실제로 NOLOCK 힌트로 데이터베이스를 낭비하지 않아야합니다. http://sqlblogcasts.com/blogs/tonyrogerson/archive/2006/11/10/1280.aspx –

답변

1

여기에 내 대답을 참조하십시오

What goes wrong when I add the Where clause?

당신은 numericCol 및 ID 모두를 포함하는, TableE에 포함 인덱스를 추가하는 시도 말한다. 그러나 쿼리를 사용하지 않은 것으로 판단됩니다. 그래서 테이블 스풀을 볼 수 있습니다.

덮어 쓰기 색인을 테이블의 유일한 색인으로 사용하거나 쿼리 힌트를 포함하여 쿼리를 사용하도록 만들 수 있습니다. 그러면 테이블 스풀이 제거되고 중첩 루프가 빨라집니다.

TableB와 동일합니다. 사용되는 인덱스가 Id에만있는 경우 NumericCol에있는 중첩 루프를 지원하지 않습니다. Id에서 인덱스를 제거하거나 쿼리 힌트를 사용하여 문제를 강제로 수행합니다.

+0

이제 TableE (id ASC, numericCol ASC)에 대한 색인과 TableB에 대한 색인 (id ASC, numericCol ASC)이 있습니다. 실행 계획에서 두 가지 모두 사용 중이지만 실행 계획은 변경되지 않지만 여전히 테이블 스풀이 있고 숫자는 같습니다. – ashishduh

+0

흠, 실행 계획의 스크린 샷으로 질문을 편집 할 수 있습니까? –