핵심 인사이트 (3줄 요약)
- 본질: 조건 푸시 다운 (Condition Pushdown)은 바깥 질의의 필터 조건을 인라인 뷰나 서브쿼리 안쪽으로 전달해, 같은 결과를 더 작은 중간 결과로 계산하게 만드는 옵티마이저 재작성이다.
- 가치: 조인·정렬·집계 전에 행 수를 먼저 줄이면 디스크 I/O (Input/Output), 메모리, 임시 영역 사용량이 함께 감소하므로, 느린 쿼리를 종종 "늦게 거르던 구조"에서 "일찍 거르는 구조"로 바꿀 수 있다.
- 판단 포인트: 모든 조건이 밀려 내려가는 것은 아니다. 집계 결과,
DISTINCT, 윈도 함수, Top-N처럼 경계 자체가 의미를 갖는 경우에는 안전한 범위만 부분 푸시다운해야 한다.
Ⅰ. 개요 및 필요성
조건 푸시 다운은 SQL (Structured Query Language) 을 사람이 읽기 좋은 형태로 나눈 뒤에도, 실행 단계에서는 가능한 한 데이터 원천에 가까운 곳에서 먼저 걸러 보자는 최적화 전략이다. 개발자는 인라인 뷰나 재사용 가능한 서브쿼리로 쿼리를 정리하지만, 비용 기반 옵티마이저 (CBO, Cost-Based Optimizer) 입장에서는 필터가 너무 바깥에 있다는 이유만으로 큰 중간 결과를 만든 뒤 나중에 버리는 상황이 자주 생긴다. 이때 조건 푸시 다운은 뷰 경계를 완전히 없애지 못하더라도, 적어도 조건만 안쪽으로 보내 조기 필터링을 수행하게 만든다.
이 기법이 필요한 이유는 비용의 대부분이 최종 결과 건수보다 중간 결과가 얼마나 오래 큰 상태로 남아 있느냐에 달려 있기 때문이다. 100만 행을 모아 놓고 마지막에 100행만 남기는 쿼리보다, 초반에 100행만 골라 그 뒤 조인과 집계를 하는 쿼리가 훨씬 싸다. 특히 큰 팩트 테이블, 파생 테이블, 분석용 집계 뷰에서는 이 차이가 응답시간과 임시 공간 사용량을 크게 바꾼다.
- 📢 섹션 요약 비유: 창고 정리를 할 때 모든 상자를 복도로 끌어낸 뒤 색깔표를 보며 고르는 것보다, 창고 안 선반에서 필요한 상자만 먼저 집어오는 편이 훨씬 덜 힘든 것과 같다.
Ⅱ. 아키텍처 및 핵심 원리
조건 푸시 다운의 핵심은 단순하다. 바깥 블록의 조건이 안쪽 블록에 들어가도 결과 의미가 바뀌지 않는다면, 그 조건을 가능한 한 이른 시점에 적용한다. 중요한 점은 뷰를 없애는 것이 아니라 조건의 적용 위치를 바꾸는 것이다. 그래서 뷰 머징 (View Merging)이 어려운 경우에도 조건 푸시 다운은 별도로 성립할 수 있다.
아래 그림은 같은 조건이 어느 단계에서 적용되느냐에 따라 중간 결과 크기가 어떻게 달라지는지 보여 준다.
┌────────────────────────────────────────────────────────────────────┐
│ Predicate placement changes the cost │
├────────────────────────────────────────────────────────────────────┤
│ Late filtering │
│ EMP 1,000,000 rows -> View V 1,000,000 -> Join -> Filter -> 120 │
│ │
│ Early filtering by pushdown │
│ EMP 1,000,000 rows -> Filter in V -> 120 -> Join -> 120 │
│ │
│ Same answer / far smaller intermediate result │
└────────────────────────────────────────────────────────────────────┘
예를 들어 다음과 같은 질의를 보자.
SELECT d.dept_name, v.emp_name, v.salary
FROM dept d
JOIN (
SELECT deptno, emp_name, salary
FROM emp
) v
ON d.deptno = v.deptno
WHERE d.dept_name = 'IT개발부';
옵티마이저는 d.dept_name = 'IT개발부' 조건을 이용해, 내부적으로는 아래와 비슷한 형태를 고려할 수 있다.
SELECT d.dept_name, v.emp_name, v.salary
FROM dept d
JOIN (
SELECT deptno, emp_name, salary
FROM emp
WHERE deptno IN (
SELECT deptno
FROM dept
WHERE dept_name = 'IT개발부'
)
) v
ON d.deptno = v.deptno
WHERE d.dept_name = 'IT개발부';
실제 실행계획은 DBMS (Database Management System) 마다 다르게 나타나지만, 핵심은 emp 전체를 먼저 읽는 대신 IT개발부 관련 부서 번호에 해당하는 행만 먼저 줄인다는 데 있다. 이때 선택도가 높은 조건일수록 이득이 크고, 적절한 인덱스가 있으면 푸시다운 이후 액세스 경로까지 좋아질 수 있다.
집계 뷰에서도 원리는 비슷하지만, 어떤 조건이 내려갈 수 있는지가 더 중요하다. 예를 들어 GROUP BY deptno 뷰에 대해 deptno = 10 조건은 그룹핑 전에 적용해도 의미가 유지되므로 내려갈 수 있다. 반면 SUM(salary) > 100000 같은 집계 결과 조건은 집계가 끝난 뒤에만 평가할 수 있으므로, 원래 위치를 유지하거나 HAVING 성격으로 다뤄야 한다.
| 조건 유형 | 푸시다운 가능성 | 이유 |
|---|---|---|
| 단순 선택 조건 | 높음 | 결과 의미를 거의 바꾸지 않고 조기 필터링 가능 |
| 조인 키 기반 조건 | 높음 | 뷰 내부 테이블 행 수를 직접 줄일 수 있음 |
| 그룹 키 조건 | 부분 가능 | 집계 전에 걸러도 같은 그룹 결과 유지 |
| 집계 결과 조건 | 낮음 | 먼저 계산해야 값이 생김 |
DISTINCT, 윈도 함수, Top-N 이후 조건 | 제한적 | 경계가 결과 의미를 결정하기 때문 |
- 📢 섹션 요약 비유: 뷔페 손님 수를 줄이려면 계산대 앞에서 한 번 더 검사하는 것보다, 입구에서 초대장 있는 사람만 먼저 들여보내는 편이 훨씬 효과적이다.
Ⅲ. 비교 및 연결
조건 푸시 다운은 자주 뷰 머징, 머티리얼라이제이션 (Materialization), 조인 순서 최적화와 함께 언급된다. 하지만 셋은 무엇을 움직이느냐가 다르다. 뷰 머징은 뷰 경계를 없애고, 조건 푸시 다운은 경계는 남기되 조건만 안으로 전달하며, 머티리얼라이제이션은 오히려 경계를 유지하고 결과를 저장한다.
| 기법 | 뷰 경계 처리 | 무엇을 바꾸는가 | 잘 맞는 상황 |
|---|---|---|---|
| 뷰 머징 (View Merging) | 경계 제거 | 질의 블록 자체를 하나로 합침 | 단순 뷰, 전역 조인 재배치가 중요한 경우 |
| 조건 푸시 다운 (Condition Pushdown) | 경계 유지 | 바깥 필터의 적용 위치를 안쪽으로 이동 | 머징은 어렵지만 조기 필터링은 가능한 경우 |
| 머티리얼라이제이션 (Materialization) | 경계 유지 + 저장 | 중간 결과를 실제로 계산해 보관 | 재사용이 많거나 경계 유지가 의미상 필요한 경우 |
실무에서는 세 기법이 경쟁 관계라기보다 조합 가능한 선택지다. 단순 뷰는 아예 머징되고, 머징이 어려운 집계 뷰는 조건만 일부 푸시다운될 수 있으며, 반복 참조되는 비싼 뷰는 반대로 머티리얼라이즈하는 편이 낫다. 따라서 "푸시다운이 되었는가?"보다 먼저 봐야 할 질문은 이 뷰 경계를 없애야 하는가, 남겨야 하는가, 남기되 안쪽은 줄일 수 있는가다.
또한 조건 푸시 다운은 조인 순서 최적화와도 직접 연결된다. 안쪽 블록의 행 수가 미리 줄면 이후 조인 순서, 조인 방식, 인덱스 선택이 모두 달라질 수 있기 때문이다. 즉 조건 푸시 다운 자체가 끝이 아니라, 후속 최적화가 더 잘 작동하도록 탐색 공간을 바꾸는 전처리라고 이해하는 편이 정확하다.
- 📢 섹션 요약 비유: 벽을 허물어 한 방으로 만드는 것이 뷰 머징이라면, 문만 열어 바람길을 먼저 트는 것이 조건 푸시 다운이고, 아예 별도 창고에 물건을 쌓아 두는 것이 머티리얼라이제이션이다.
Ⅳ. 실무 적용 및 기술사 판단
실무에서 조건 푸시 다운 이슈는 대개 "뷰로 정리했더니 왜 느려졌는가", "집계 뷰 위에 조건을 걸었는데 왜 전체 스캔이 나는가" 같은 형태로 나타난다. 이때 핵심은 SQL을 다시 쓰는 기술보다, 옵티마이저가 조건을 안쪽으로 밀어도 되는 구조인지를 만들어 주는 것이다.
가장 먼저 볼 것은 비선형 표현과 불필요한 경계다. 예를 들어 TO_CHAR(order_date, 'YYYYMM') = '202605'처럼 컬럼을 함수로 감싸면, 푸시다운이 되더라도 인덱스 접근 이점이 줄어들 수 있다. 반면 order_date >= DATE '2026-05-01' AND order_date < DATE '2026-06-01'처럼 범위 조건으로 쓰면, 푸시다운과 인덱스 활용이 동시에 유리해진다.
기술사 판단 체크리스트
- 바깥 조건이 안쪽 뷰 행 수를 실제로 많이 줄이는가?
- 조건이 그룹 키, 조인 키, 단순 선택 조건인지, 아니면 집계 결과·순위·윈도 결과인지 구분했는가?
- 뷰 내부에
DISTINCT,ORDER BY, 윈도 함수, Top-N처럼 의미 경계가 있는가? - 실행계획에서 큰
VIEW결과나 임시 영역 사용이 병목으로 보이는가? - 통계 정보와 인덱스 상태가 최신인가?
- 힌트 사용 전에 SQL 구조 단순화와 조건 식 재작성부터 검토했는가?
자주 나오는 안티패턴
- 읽기 좋게 만든 뷰 위에 조건을 몰아놓고, 뷰 내부는 아무 필터 없이 둔 채 성능 저하를 방치하는 경우
- 집계 결과 조건과 그룹 키 조건을 구분하지 않고 "다 내려가겠지"라고 가정하는 경우
DISTINCT나 불필요한 정렬을 습관처럼 넣어 푸시다운 여지를 스스로 없애는 경우- 통계 불량 상태에서 힌트만으로 푸시다운을 강제해 계획을 불안정하게 만드는 경우
결국 조건 푸시 다운의 실무 판단은 "필터를 더 안쪽으로 보낼 수 있는가?"보다 "보내도 의미가 안 바뀌고, 보내면 실제 비용이 줄어드는가?"를 확인하는 일이다. 기술사 답안에서도 무조건 가능/불가로 단정하기보다, 안전성·선택도·후속 최적화 효과를 함께 설명해야 깊이가 생긴다.
- 📢 섹션 요약 비유: 장부를 빨리 찾고 싶다고 도서관 분류 체계를 무시하면 안 된다. 빨리 찾되, 서가 체계가 망가지지 않는 선에서 가장 앞단에서 걸러야 한다.
Ⅴ. 기대효과 및 결론
조건 푸시 다운이 잘 작동하면 조인 이전의 행 수가 줄어들어 디스크 I/O (Input/Output), 메모리 사용량, 임시 정렬 공간, 네트워크 전송량까지 함께 줄어든다. 특히 대용량 분석 SQL, 뷰 기반 보고서, 원격 테이블 접근, 대형 조인 쿼리에서는 "같은 결과를 더 빨리" 만드는 대표적인 재작성 효과를 볼 수 있다.
하지만 한계도 분명하다. 선택도가 낮은 조건은 푸시다운해도 이득이 작을 수 있고, 잘못된 기수성 (Cardinality) 추정 아래에서는 옵티마이저가 기대만큼 좋은 계획을 만들지 못할 수도 있다. 또한 보안 경계, 의미 보존, 집계 결과 조건처럼 경계를 남겨야 하는 경우에는 무리한 푸시다운이 오히려 위험하다.
결론적으로 조건 푸시 다운은 "WHERE 절을 안쪽으로 옮기는 꼼수"가 아니다. 행 수를 줄이는 시점을 데이터 원천에 최대한 가깝게 당겨, 후속 조인과 집계 비용 전체를 낮추는 옵티마이저 사고방식으로 기억하는 것이 맞다.
- 📢 섹션 요약 비유: 긴 여행에서 짐을 줄일 수 있다면 목적지에 도착해서 버릴 것이 아니라, 출발하기 전에 가방 안에서 먼저 빼는 편이 훨씬 현명하다.
📌 관련 개념 맵
| 개념 | 연결 포인트 |
|---|---|
| 비용 기반 옵티마이저 (CBO, Cost-Based Optimizer) | 푸시다운 가능성과 비용 절감 효과를 판단하는 주체 |
| 뷰 머징 (View Merging) | 경계를 제거하는 형제 재작성 기법 |
| 머티리얼라이제이션 (Materialization) | 경계를 유지하고 중간 결과를 저장하는 대비 전략 |
| 조인 순서 최적화 (Join Order Optimization) | 푸시다운 이후 더 좋아질 수 있는 후속 최적화 |
| 기수성 (Cardinality) 추정 | 푸시다운 이득을 계산하는 통계 기반 |
| SARGable 조건 | 푸시다운 이후 인덱스 접근 이점을 살리기 쉬운 조건 형태 |
| 집계 푸시다운 | 그룹 키 조건처럼 일부 집계 뷰에 적용되는 확장 개념 |
📈 관련 키워드 및 발전 흐름도
Outer predicate discovered
│
▼
Safety check on view boundary
│
├──────────────► keep predicate outside
▼
Predicate moved into view
│
▼
Earlier row reduction
│
▼
Cheaper join / sort / aggregation
│
▼
Lower overall query cost
이 흐름도는 "바깥 조건 발견 → 안전성 검사 → 안쪽 이동 여부 결정 → 조기 필터링 → 후속 연산 비용 절감"이라는 조건 푸시 다운의 핵심 판단 절차를 요약한다.
👶 어린이를 위한 3줄 비유 설명
- 사탕을 고를 때 상자를 전부 쏟아 놓고 찾는 것보다, 상자 안에서 딸기맛만 먼저 고르면 더 빨라요.
- 데이터베이스도 필요한 것만 먼저 골라 놓으면 뒤에서 섞고 계산하는 일이 훨씬 쉬워져요.
- 하지만 모양을 다 만든 뒤에만 고를 수 있는 조건은 너무 일찍 고르면 안 돼요.