[친절한 SQL 튜닝] 5.1~5.2 소트 튜닝

wally·2022년 11월 28일
0

5.1 소트 연산에 대한 이해

5.1.1 소트 수행 과정

  • 소트는 PGA 에 할당한 Sort Area 에서 이루어진다.
  • 메모리 공간인 Sort Area 가 다 차면, 디스크 Temp 테이블스페이스를 활용한다.
    • 메모리 소트(In-Memory Sort) : 전체 데이터의 정렬 작업을 메모리 내에서 완료 (=Internal Sort)
    • 디스크 소트(To-Disk Sort) : 할당받은 Sort Area 내에서 정렬을 완료하지 못해 디스크까지 활용 (=External Sort)

디스크 소트 과정

  1. 소트할 대상 집합을 SGA 버퍼캐시를 통해 읽어 Sort Area 에서 정렬 시도.
  2. 양이 많은 경우 정렬된 중간집합을 Temp 테이블스페이스에 임시 세그먼트를 만들어 저장(=Sort Run)
  3. 최종적으로 다시 merge한다.
  • 소트 연산은 메모리집약적이면서 CPU 집약적이다.
  • 처리할 데이터가 많으면 디스크 I/O 도 발생한다.
  • 부분범위 처리를 불가능하게 함으로써 OLTP 환경에서 성능 저하의 주요인이다.
  • 따라서 SQL 작성시 Sort 가 발생하지 않도록 작성해야 하고, 소트가 불가피하다면 메모리 내에서 수행을 완료할 수 있게 한다.

5.1.2 소트 오퍼레이션

(1) Sort Aggregate

  • 전체 로우를 대상으로 집계를 수행할 때 나타난다.
  • 실제 데이터 정렬은 하지 않는다.
  • Sort Area 를 사용한다는 의미이다.

(2) Sort Order By

  • 데이터를 정렬할 때 나타난다.

(3) Sort Group By

  • 소팅 알고리즘을 사용해 그룹별 집계를 수행할 때 나타난다.
  • Group 컬럼에 해당하는 메모지를 미리 만들어 두고 그 안에서 SUM, MAX, MIN, COUNT 를 누적식으로 적용시킨다.
  • 해당 컬럼개수가 늘어나면 중간에 끼어 새로 만들면 된다.
  • 해시 기법인 Hash Group BY 도 존재한다.
  • 부서(그룹 개수)가 많지 않다면 대상 레코드가 아무리 많아도 Temp 테이블스페이스를 쓸 일이 없다.
  • 그룹필 결과는 정렬 순서를 보장하지 않는다.
  • Sort Group By 는 소팅 알고리즘을 사용해 값을 집계한다는 뜻이지 결과의 정렬을 의미하지 않는다
  • 정렬된 그룹핑 결과를 얻고자 한다면, 실행계획에 설령 Sort Group By라고 표시되더라도 반드시 Order By를 명시해야 한다.

(4) Sort Unique

  • 서브쿼리 Unnesting 과정에서 메인 쿼리와 조인하기 전에 중복 레코드를 제거할때 나타난다.
  • Union, Minus, Intersect 같은 집합(Set) 연산시 나타난다.
  • Distinct 사용시 나타난다.

(5) Sort join

  • 소트 머지 조인 수행시 나타난다.

(6) Window Sort

  • 윈도우 함수(=분석 함수) 수행시 나타난다.

5.2 소트가 발생하지 않도록 SQL 작성

  • SQL 작성 시 불필요한 소트가 발생하지 않도록 주의해야 한다.
  • Union, Minus, Distinct 는 중복 레코드를 제거하기 위해소트 연산을 발생시키므로 꼭 필요한 경우에만 사용하자

5.2.1 Union vs Union All

  • Union 은 상단 하단 두 집합 간 중복을 제거하기 위해 소트 작업을 수행한다.
  • Union All 은 중복을 확인하지 않고 두 집합을 단순히 결합하여 소트 연산을 수행하지 않는다.
  • 따라서 Union All 을 사용하는 것이 성능적으로 좋다.
  • 다만 Union 을 Union All 로 변경시에는 결과 집합이 달라질 수 있다.
  • 중복 가능성이 없는 경우 Union All 를 쓰면 되지만 중복 가능성이 존재하는 경우 where 절에 and 로 조건을 추가하는 방식으로 추가적인 SQL 작성이 필요하다(책 p345 참고)

5.2.2 Exists 활용

  • Distinct 사용시 데이터를 모두 읽어 중복을 제거하며 이 과정에서 많은 I/O 가 발생한다.
  • Exists 서브쿼리는 데이터 존재 여부만 확인하면 되기 때문에 조건절을 만족하는 데이터를 모두 읽지 않는다.
  • Distinct 연산자를 사용하지 않으므로 해당 테이블에 대한 부분범위 처리도 가능하다.
  • Distinct, Minus 연산자를 사용한 쿼리는 대부분 Exists 서브쿼리로 변환 가능하다.

5.2.3 조인 방식 변경

  • 조인문일때는 조인 방식도 잘 선택해주어야 한다.
  • 책 p 349
profile
클린코드 지향

0개의 댓글