2014-01-06 5 views
1

현재 쿼리에 성능 문제가 있습니다 (아래 예제보다 복잡합니다). 원래 쿼리가 실행되고 30 초가 걸렸다면 대신 테이블 변수를 사용하여 임시 테이블을 사용하도록 전환하면 속도가 몇 초로 줄었습니다. 해결임시 테이블과 테이블 변수를 사용하면이 쿼리의 속도가 향상되는 이유는 무엇입니까?

SELECT 
    ParamValues.ID.value('.','VARCHAR(100)') AS 'Code' 
INTO 
    #tCodes 
FROM 
    @xmlCodes.nodes('/ArrayOfString/string') AS ParamValues(ID) 


SELECT 
    'SummedValue' = SUM(ot.[Value]) 
FROM 
    [SomeTable] st (NOLOCK) 
JOIN 
    [OtherTable] ot (NOLOCK) 
    ON ot.[SomeTableID] = st.[ID] 
WHERE 
    ot.[CodeID] IN (SELECT [Code] FROM #tCodes) AND 
    st.[Status] = 'ACTIVE' AND 
    YEAR(ot.[SomeDate]) = 2013 AND 
    LEFT(st.[Identifier], 11) = @sIdentifier 

I는 성능이 문제 : 여기

-- Store XML into tables for use in query 
DECLARE @tCodes TABLE([Code] VARCHAR(100)) 

INSERT INTO 
    @tCodes 
SELECT 
    ParamValues.ID.value('.','VARCHAR(100)') AS 'Code' 
FROM 
    @xmlCodes.nodes('/ArrayOfString/string') AS ParamValues(ID) 


SELECT 
    'SummedValue' = SUM(ot.[Value]) 
FROM 
    [SomeTable] st (NOLOCK) 
JOIN 
    [OtherTable] ot (NOLOCK) 
    ON ot.[SomeTableID] = st.[ID] 
WHERE 
    ot.[CodeID] IN (SELECT [Code] FROM @tCodes) AND 
    st.[Status] = 'ACTIVE' AND 
    YEAR(ot.[SomeDate]) = 2013 AND 
    LEFT(st.[Identifier], 11) = @sIdentifier 

더 빠르게 수행하는 임시 테이블 버전이다 : 여기

는 다운 트리밍 버전 테이블 변수를 사용 변경 사항은 있지만 문제가 수정 된 이유를 이해하지 못하고 이유를 알고 싶어합니다. 그것은 쿼리의 다른 것과 관련 될 수 있지만, 저장 프로 시저 (훨씬 더 복잡함)에서 변경된 것은 테이블 변수를 사용하여 임시 테이블을 사용하는 것으로 전환하는 것입니다. 이견있는 사람?

+1

이 기사를 매우 유익하게보십시오 http://sqlserverplanet.com/tsql/yet-another-temp-tables-vs-table-variables-article –

+0

@Steve Wellens Google ... 누가 사용하려고 생각 했습니까? 여기에 오기 전에 질문을 게시 하시겠습니까 ??? – Kelsey

+0

@ M.Ali는 링크에 감사 드리며, 내가 읽은 다른 것들과 비슷하지만, 나의 결과는 의심 스러웠던 것과는 정반대 인 것 같다. – Kelsey

답변

1

표 변수와 #temp 표 간의 차이점과 유사점은 in my answer here입니다.

표시된 두 쿼리 (인덱싱되지 않은 테이블 변수와 인덱싱되지 않은 임시 테이블 비교)는 세 가지 가능성이 있습니다.

  1. INSERT ... SELECT to table 변수는 항상 serial입니다. SELECT은 임시 테이블에 대해 병렬 처리 할 수 ​​있습니다.
  2. 임시 테이블에는 열 통계 히스토그램이 자동으로 만들어집니다.
  3. 일반적으로 테이블 변수의 카디널리티는 (테이블이 비어있을 때 그들이 컴파일 할 때) 당신이 (3) 가장 가능성있는 설명을 보인다 보여 코드에서

0 것으로 간주됩니다.

테이블 변수를 채운 후에 문을 다시 컴파일하려면 OPTION (RECOMPILE)을 사용하여이 문제를 해결할 수 있습니다.