ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Hash Match(Aggregate)와 Stream Aggregate in SQL Server 2008
    SQL Server/실행계획 연산자 2011. 7. 11. 18:48
    안녕하세요. 이스트럭(강동운) 입니다.

    이번에 알아볼 주제는 Hash Match(Aggregate) 와 Stream Aggregate 입니다.

    두개는 집계를 하는 실행 계획 연산자 입니다.
    따라서.. 집계를 하는.. SUM, COUNT 또는 GROUP BY 등이 이들 연산자를 사용하게 됩니다.


    두가지 연산자의 큰 차이점은.. 아래 두가지로 구분이 됩니다.
    바로.. 정렬이 보장된다(Stream Aggregate) 와.. 정렬이 보장되지 않는다.(Hash Match(Aggregate))
    입니다.


    예제를 살펴보도록 하겠습니다.


    테스트 VERSION
    Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (X64)   Mar 29 2009 10:11:52
    Copyright (c) 1988-2008 Microsoft Corporation  Developer Edition (64-bit) on Windows NT 6.1 <X64> (Build 7600: ) 

    USE tempdb

    GO

    IF OBJECT_ID('TEST','U') IS NOT NULL

           DROP TABLE TEST

    GO

    CREATE TABLE TEST( A INT NOT NULL, B INT NOT NULL)

    GO

    --//유니크 하지 않은 넌 클러스터드 인덱스를 생성한 경우

    CREATE INDEX NC_TEST_A ON TEST(A)

    GO

     

    SET NOCOUNTON

    GO

     

    DECLARE @I INT = 1

     

    WHILE(@I <= 10000)

    BEGIN

           INSERT INTO TEST SELECT @I, CONVERT(INT,RAND()* 1000) +1

           SET @I = @I + 1

    END

    SET NOCOUNTOFF

    GO

     

    SELECT

           B

    FROM TEST

    GROUP BY B

    --//실행 계획


    --//결과 화면(정렬이 되지 않았습니다.)



    --//B에는 아무런 인덱스가 없기 때문에 Hash Match를 선택했습니다.

    --//하지만 정렬된 A 컬럼은 어떻게 될까요?

     

    SELECT

           A

    FROM TEST

    GROUP BY A

     

    --//실행 계획


    --//결과 화면



    정렬이 되어있습니다~!


    근데 만약 A가 유니크한 인덱스라면 어떻게 될까요??


    DROP INDEX TEST.NC_TEST_A

    GO

    --//유니크  넌러스터드 인덱스로 생성한 경우

    CREATE UNIQUE INDEX NC_TEST_A ON TEST(A)

    GO



    SELECT

           A

    FROM TEST

    GROUP BY A

    --//실행 계획



    Index Scan만 해도 이미 데이터가 정렬이 되있고 유니크 하기 때문에.. 따로 Stream Aggregate 를 수행하지 않습니다.




    여기서 하나 궁금한 점! 인덱스가 없는 컬럼은 항상 Hash Match만 쓰게 될까요?


    건수를 2519개만 넣고.. 통계를 일정하게 하기 위해 B에 같은 데이터를 넣었습니다.


    IF OBJECT_ID('TEST','U') IS NOT NULL

           DROP TABLE TEST

    GO

    CREATE TABLE TEST( A INT NOT NULL, B INT NOT NULL)

    GO

     

    SET NOCOUNTON

    GO

     

    DECLARE @I INT = 1

     

    WHILE(@I <= 2519)

    BEGIN

           INSERT INTO TEST SELECT @I, @i

           SET @I = @I + 1

    END

    SET NOCOUNTOFF

    GO


    SELECT

           B

    FROM TEST

    GROUP BY B

    --//실행 계획



    이는 Hash Match 하는 비용보다 Sort 하는 비용이 작기 때문에 이렇게 처리를 한 것 같습니다.


    하지만 어느 경우일때 이런 현상이 생기는 지는 아직 밝혀내지 않았습니다 ^^..


    혹시 아시는 분 계시면 댓글 부탁드립니다.


    감사합니다 ^^



    작 성일: 2011.07.11

Designed by Tistory.