5.4장 Sort Area 효율적으로 쓰는 SQL 작성법

친절한 SQL 튜닝 5.4장

스터디하면서 알게 된 정렬 관련 실전 팁을 정리했다. 불필요한 sort area 사용을 줄이기 위한 실제 쿼리 튜닝 사례 위주다.

1. Sort 데이터 줄이기

다음 두 쿼리는 결과는 같지만, 정렬 대상과 시점이 다르다.

-- (1) 가공 후 정렬
SELECT LPAD(상품번호, 30) || LPAD(상품명, 30) || LPAD(고객ID, 30) || LPAD(고객명, 30) || TO_CHAR(주문일시, 'yyyymmdd hh24:mi:ss')
FROM 주문상품
WHERE 주문일시 BETWEEN :START AND :END
ORDER BY 상품번호;
-- (2) 정렬 후 가공
SELECT LPAD(상품번호, 30) || LPAD(상품명, 30) || LPAD(고객ID, 30) || LPAD(고객명, 30) || TO_CHAR(주문일시, 'yyyymmdd hh24:mi:ss')
FROM (
  SELECT 상품번호, 상품명, 고객ID, 고객명, 주문일시
  FROM 주문상품
  WHERE 주문일시 BETWEEN :START AND :END
  ORDER BY 상품번호
);
  • 첫 번째 쿼리는 LPAD와 TO_CHAR로 가공한 후 정렬하기 때문에, 가공된 긴 문자열 전체를 sort area에 적재하게 된다.

  • 두 번째 쿼리는 정렬 후 가공하므로, 정렬 시점의 데이터 양이 작아져 sort area 사용량이 줄어든다.

단순 예시로 다음도 마찬가지다.

→ 정렬 시 불필요한 컬럼을 빼는 것만으로도 sort I/O를 줄일 수 있다.

2. Top-N 쿼리는 정렬을 ‘다’ 하지 않는다

Top-N 쿼리에서는 Oracle이 일반 정렬이 아닌, Top-N Sort 알고리즘을 사용한다.

작동 방식은 다음과 같다

  1. 처음 N개의 레코드를 읽어 정렬

  2. 이후 레코드를 하나씩 읽으면서 N등보다 크면 삽입, 가장 작은 값은 제거

  3. 최종적으로 N개의 레코드만 남긴다

장점

  • 전체 정렬이 아니므로 메모리 사용량이 적다

  • 인덱스로 소트 연산을 생략할 수 없어 Table Full Scan 방식 시 SORT ORDER BY STOPKEY 를 사용한다.

3. Top-N 조건이 없으면 정렬은 끝까지 수행된다

ROWNUM 또는 FETCH FIRST 조건이 없는 경우, 전체 데이터를 정렬해야 하므로 sort 부하가 커질 수 있다.

또한 다음과 같은 윈도우 함수는 MAX()보다 효율적인 정렬을 할 수 있다.

  • RANK(), ROW_NUMBER() → 내부적으로 Top-N 정렬 사용

Last updated