PARTITION BY는 작업 단위를 나누고
ORDER BY는 각 단위 안의 순서를 요구합니다. 실행계획은
“입력을 얼마나 줄였는가, 정렬을 피했는가, 파티션이 메모리에 남는가”
순서로 읽으면 병목이 빨리 드러납니다.
인덱스 순서
인덱스는 파티션 키 다음 정렬 키 순서로 맞춘다
CREATE INDEX idx_emp_dept_salary
ON employees (department, salary DESC, employee_id);
SELECT name, department, salary,
ROW_NUMBER() OVER (
PARTITION BY department
ORDER BY salary DESC, employee_id
) AS rn
FROM employees
WHERE active = true;
축소WHERE active = true가 입력 행을 먼저 줄인다
묶음department가 파티션 경계를 만든다
순서salary DESC, employee_id가 정렬 요구를
고정한다
비용 흐름
비용은 입력 축소, 정렬, 프레임 보관 순서로 커진다
입력 축소WHERE, JOIN, GROUP BY로 윈도우에 들어갈 행을 먼저
줄인다.인덱스 순서PARTITION BY 다음 ORDER BY 키가 맞으면 정렬을 줄인다.Sort메모리를 넘으면 temp spill이 생기는 가장 흔한 병목이다.WindowAgg정렬된 파티션을 읽으며 순위와 프레임 값을 계산한다.바깥 필터rn <= 3 같은 조건은 계산 뒤 적용되므로 입력을 줄이지
않는다.
위험 신호Sort와 큰 프레임이 동시에 보이면 정렬 키, 파티션 크기,
work_mem/temp 사용량을 먼저 본다.
1 입력 축소WHERE / JOIN / GROUP BY
행 수를 줄일수록 유리
2 인덱스 순서파티션 + 정렬 키
정렬 생략 가능성
3 정렬정렬 / 임시공간 / 디스크 밀림
가장 흔한 병목
4 프레임 보관ROWS / RANGE / FOLLOWING
참조 범위가 비용
5 바깥 필터순위 조건 / 바깥 SELECT
계산 뒤 거르는 비용
실행계획 점검
느린 지점을 실행계획 신호로 분리한다
요인느려지는 조건확인 방법
정렬 키윈도우마다 서로 다른 ORDER BY 요구Sort 노드 수와 정렬 키 비교
파티션 크기한 파티션에 행이 몰려 메모리 상한 초과파티션별 행 분포와 temp 사용량
프레임뒤쪽 행까지 참조해 많은 행을 보관ROWS/RANGE와 FOLLOWING 범위
오해 방지
Top-N은 계산 전 축소와 계산 후 필터를 구분한다
ROW_NUMBER() 결과는 대개 바깥 SELECT에서 필터링합니다.
그래서 rn <= 3 자체가 입력을 줄여 주지는 않습니다.
먼저 줄일 수 있는 조건은 안쪽 WHERE나 JOIN 조건에 두고,
순위 필터는 바깥에서 적용합니다.
같은 PARTITION BY/ORDER BY를 여러 번 쓰면
WINDOW 절이나 동일한 OVER 정의로 묶어 중복 정렬 가능성을 낮춥니다.
재사용
같은 윈도우 정의 재사용
동일한 PARTITION BY/ORDER BY는 WINDOW 절
또는 같은 OVER 절로 묶어 정렬 중복을 줄입니다.
커버링
필요 컬럼 범위 확인
인덱스 순서가 맞아도 테이블 랜덤 조회가 커지면 병목이 정렬에서
조회로 이동합니다.
메모리
정렬 메모리와 임시 파일
PostgreSQL은 work_mem, 다른 DBMS는 tempdb/PGA 같은 정렬
작업 공간을 확인합니다.
Top-N
Top-N 필터 위치
순위 필터는 바깥 SELECT에서, 입력 축소 조건은 안쪽 쿼리에서 처리해야
실제 작업량이 줄어듭니다.