소트 머지 조인과 해시 조인의 경우 

 - 소트 머지 조인의 경우 

    ● 소트 머지 조인은 PGA상에 정열된 집합을 통해 조인 엑세스가 일어나기 때문에 

          Random 엑세스 발생량보다는 소트 부하에 의해 성능이 결정된다. 

    ● 디스크 소트가 발생할 정도의 큰 테이블을 포함할 때는 큰 테이블을 드라이빙하는 것이 

          더 빠르지만, 

    ● 메모리 소트 방식으로 조인할 때는 작을 쪽 테이블을 드라이빙하는 것이 조금 더 빠르다. 

 - 해시 조인의 경우 

     해시 조인은 Hash Area에 build Input을 모두 채울 수 있느냐가 관건이므로 

       두말할 것도 없이 작은 쪽 테이블을 드라이빙하는 것이 유리하다. 

기본 메커니즘 

 - 둘 중 작은 집합(Build input)을 읽어 Hash Area에 해시 테이블을 생성하고, 

   반대쪽 큰 집합을 읽어 해시 테이블을 탐색하면서 조인하는 방식이다. 

 - 해시 조인은, NL 조인처럼 조인 과정에서 발생하는 Random 엑세스 부하가 없고 

   소트 조인처럼 조인 전에 미리 양쪽 집합을 정렬하는 부담도 없다. 

   (다만, 해시 테이블을 생성하는 비용이 수반된다. 

    따라서 Build Input이 작을 때라야 효과적이다.)

 - Build Input이 Hash Area 크기를 초과한다면 디스크에 썼다가 다시 읽어 들이는 과정을 

   거치기 때문에 성능이 많이 저하된다. 

 - 해시 키 값으로 사용되는 컬럼에 중복값이 거의 없을 때라야 효과적이다. 

 - 해시 테이블을 만드는 단계는 전체범위처리가 불가피하지만 반대쪽 Probe Input을 

   스캔하는 단계는 NL 조인처럼 부분범위처리가 가능하다. 

 - 해시 조인은 래치 획득 과정 없이 PGA에서 빠르게 데이터를 탐색한다. 

 

힌트를 이용한 조인 순서 및 Build Input 조정 

 - 테이블이 2개만 있을 시 ordered, leading 힌트와 use_hash 힌트만 가지고 build input 테이블 

    선택이 가능 

 - 테이블이 3개 이상일 시 swap_join_input 힌트를 통해서 Build input 테이블 순서 조절 가능


Build input이 Hash Area를 초과할 때 처리 방식 

 - Grace 해시 조인 

      파티션 단계 

         - 조인되는 양쪽 집합 모두 조인 컬럼에 해시 함수를 적용하고, 

            반환된 해시 값에 따라 동적으로 파티셔닝 실시

         - 파티션 단계에서 양쪽 집합을 모두 읽어 디스크 상의 Temp 공간에 일단 저장해야 하므로

           In-Memory 해시 조인보다 성능이 크게 떨어지게 된다. 

      조인 단계 

         - 파티션 단계가 완료되면 각 파티션 짝에 대해 하나씩 조인을 수행한다. 

           파티션하기 전 어느 쪽이 작은 테이블이었는지 상관없이 각 파티션 짝별로 작은 쪽 

           파티션을 Build Input으로 선택해 해시 테이블을 생성한다. 

         - 해시 테이블이 생성되고 나면 반대쪽 파티션 로우를 하나씩 읽으면서 해시 테이블을 

           탐색하며, 모든 파티션 짝에 대한 처리가 완료될 때까지 이런 과정을 반복한다.     


 - Hybrid 해시 조인 

      - 순서는 책에 있으나 크게 중요한 것인지 모르겠음 ( 다 쓰기 너무 길다...) 

      - 그래서 결국 중요한 것은 Grace 해시 조인과 비교해서 실제 조인에 성공할 만한 값들만 

         걸러네서 조인하는 것


 - Recursive 해시 조인 (= Nested-loops 해시 조인) 

      - 디스크에 기록된 파티션 짝끼리 조인을 수행하려고 '작은 파티션'을 메모리에 로드하는

        과정에서  또다시 가용 Hash Area를 초과하는 경우 추가 파티셔닝을 단계를 거치게 되는데,

        이를 'Recursive 해시 조인'이라고 한다. 

     -  Recursive 해시 조인을 'Multipass 해시 조인'이라고도 함 

        Onepass 해시 조인은 디스크 쓰기가 발생했지만 Multipass 오퍼레이션을 거치지 않은 경우

        Optimal 해시 조인dms 디스크를 전혀 사용하지 않은 In-Memory 해시 조인 

  

 - 비트- 벡터 필터링

     - 조인 성공 가능성이 없는 파티션 레코드는 아예 디스크에 기록되지 않게 하려는 것 

     - 조인 단계에서 실패할 수 밖에 없는 레코드를 디스크에 기록하지 않고 버린다면, 

        이를 다시 읽어 들여 조인하지 않아도 되므로 Grace Hash 조인의 성능을 

        크게 향상시킬 수 있다.

 Build input 해시 키 값에 중복이 많을 때 발생하는 비효율

     - 해시 알고리즘의 성능은 해시 충돌을 얼마나 최소화할 수 있느냐에 달렸다. 

       이를 방지하려면 그만큼 많은 해시 버킷을 할당해야 한다. 

     - 해시 버킷을 아무리 많이 할당하더라도 해시 테이블에 저장할 키 컬럼에 중복 값이 많다면 

       하나의 버킷에 많은 엔트리가 달릴 수 밖에 없다.   

     - 해시 조인에서 해시 키는 '=' 조인 컬러만으로 결정된다.


해시 조인 사용기준 

     ● 해시 조인 성능을 좌우하는 두가지 포인트 

         - 한 쪽 테이블이 Hash Area에 담길 정도로 충분히 작아야 함 

         - Build Input 해시 키 컬럼에 중복 값이 거의 없어야 함 

     ● 해시 조인을 효과적으로 사용하는 경우 

         - 조인 컬럼에 적당한 인덱스가 없어서 NL 조인이 비효율적일 때 

         - 조인 컬럼에 인덱스가 있더라도 NL 조인 드라이빙 집합에서 Inner 쪽 집합으로의 

            조인 엑세스량이 많아 Random 엑세스 부하가 심할 때 

         - 소트 머지 조인하기에는 두 테이블이 너무 커 소트 부하가 심할 때 

            ( 우선 등치 조건과 sort가 필요 없다는 것은 기본일 듯 ) 

         - 수행빈도가 낮고 쿼리 수행 시간이 오래 걸리는 대용량 테이블을 조인할 때 

     ● 해시 조인의 남용 시 발생할 수 있는 문제들 

         - 수행빈도가 높은 쿼리에 해시 조인을 사용하면 CPU와 메모리 사용률을 크게 증가 시킴

         - 래치 경합이 발생해 시스템 동시성을 떨어뜨리게 된다. 

            ( SQL memory manager workare 

              , row cache objects , simulator hash latch, cache buffers chains ) 

         - 단적으로 말해 OLTP 환경에서는 해시 조인을 쓰는 것은 가급적 자제해야 함 

기본 매커니즘 

 - sort merge 조인은 실제 조인 오퍼레이션 과정은 NL 조인과 다르지 않다. 

   NL 조인과 마찬가지로 outer 조인할 때 순서가 고정된다. 

 - Sort Area는 PGA 영역에 할당되므로 SGA를 경유해 인덱스와 테이블을 엑세스할 때보다

   훨씬 빠르다. ( PGA 사용시 래치 획득 과정이 없다. ) 

 - use_merge 힌트를 사용한다. 

 

소트 머지 조인의 특징 

 - 소트 머지 조인은 조인을 위해 실시간으로 인덱스를 생성하는 것과 다름없다. 

   ( 그래서 조인 컬럼에 인덱스가 없는 상황에서 두 테이블을 독립적으로 읽어 

     조인 대상을 줄일 수 있을 때 유리 ) 

 - 스캔 위주의 엑세스 방식을 사용한다는 점도 소트 머지 조인의 중요한 특징 

 - 하지만, 양쪽 집합에서 정렬 대상 레코드를 찾는 작업만큼은 인덱스를 이용해 random access

   ( 그때 발생하는 random 엑세스랴잉 많다면 소트 머지 조인의 이점이 사라질 수 있음 )


소트 머지 조인이 유용할 때 

 - First 테이블에 소트 연산을 대체할 인덱스가 있을 때 

 - 조인할 First 집합이 이미 정렬돼 있을 때 

 - 조인 조건식이 등치(=) 조건이 아닐 때 


First 테이블에 소트 연산을 대체할 인덱스가 있을 때 

 - 소트 머지 조인은 한쪽 집합은 전체 범위를 처리하고 다른 한쪽은 일부만 읽고 멈추도록 

   할 수 있다. First 테이블 조인 컬럼에 인데스가 있을 때 그렇다. 

    ( sort 연산 생략은 실행계획에 sort join이 하나 밖에 나타나지 않는다. )

 - Second 테이블 조인 컬럼에 대한 인덱스를 이용함에도 Sort Join 오퍼레이션이 나타나지만 

   이때는 소트 연산에 의한 부하가 크지 않다. 

 - 또, 항상 first 테이블을 먼저 읽는 것은 아니다. Second 테이블을 읽어 정렬한 결과를 

   Sort Area에 담는다. 조인 연산을 진행할 때는 first 인덱스 부터 읽기 시작한다. 


소트 머지 조인에서의 부분범위 처리 활용 

 - Second 테이블은 항상 정렬을 수행하므로 전체범위처리가 불가피하지만 First 테이블만큼은 

   중간에 읽다가 멈출 수 있다는 뜻이다. 

   ( 여기서 second 테이블의 전체범위처리가 불가피하다라는 것이 항상 헷갈렸는데 여러번 

     읽고 생각한 것은 second 테이블은 인덱스를 읽어서 부분집합을 만들게 되면 결국은 

     그 부분집합은 다 읽어질 수 밖에 없다. 아마도 그러한 부분을 전체범위처리가 불가피하다 

     라고 표현하지 않았나 싶다. ) 


조인할 First 집합이 이미 정렬 돼 있을 때 

 - 우선, 조인할 First 집합이 조인 컬럼 기준으로 이미 정렬된 상태는 in-line view 에서

    in-line view 안에 group by , order by, distinct  연산을 먼저 수행한 경우, 

    그때는 조인을 위해 다시 정열하지 않아도 되므로 소트 머지 조인이 유리하다. 

 - outer 테이블을 group by 하고서도 sort join 오퍼레이션이 나타날 수 있는데 

   그것은 hash group by로 처리했기 때문이다. 

   이때는 order by를 추가해주면 실제 정렬작업 없이 sort join을 생략할 수 있다. 

 - Second 집합에서는 order by를 추가하더라도 sort join이 발생한다. 


조인 조건식이 등치(=) 조건이 아닐 때 

 - 해시 조인은 조인 조건식이 등치(=) 조건일 때만 사용할 수 있다. 

+ Recent posts