Search
Duplicate

7장 - 서브쿼리

상태
Done
생성자
7장 - 서브쿼리

개요

서브쿼리란 SQL 내부에서 작성되는 일시적인 테이블
기능적 관점에서 서브쿼리와 테이블은 동일
비기능적인(특히 성능적인) 관점에서 서브쿼리와 테이블은 차이가 있다.

21강. 서브쿼리가 일으키는 폐해

1.
서브쿼리의 문제점
연산 비용 추가 - 서브쿼리는 실제 데이터를 저장하고 있지 않기 때문에 서브쿼리를 사용할 때마다 SELECT 구문이 실행된다.
데이터 I/O 비용 발생 - 연산 결과를 저장해야 하는데, 메모리가 부족하다면 TEMP 탈락이 발생하여 성능이 급격히 떨어질 수 있다.
최적화를 받을 수 없음 - 서브쿼리에는 테이블과는 달리 인덱스와 같은 메타데이터가 없기에 옵티마이저가 최적화를 할 수 없다.
2.
서브쿼리 의존증
다음과 같은 테이블에서 고객별 최소 순번 레코드를 구하고자 한다.
구하고자 하는 레코드들
이 문제에서 어려운 점은 순번의 최솟값이 고객마다 다르기 때문에, 최솟값을 동적으로 구해야 한다는 점이다.
서브쿼리를 사용한 방법
→ 고객들의 최소 순번 값을 저장하는 서브쿼리를 만들고, 기존의 Receipts 테이블과 결합한다.
위 쿼리의 작동 방식
서브쿼리를 사용한 방식의 단점
1.
가독성이 떨어진다.
2.
성능이 나쁘다.
→ 성능이 나쁜 4가지 이유
윈도우 함수를 사용한 방법
SQL 튜닝에서 가장 중요한 부분은 I/O를 줄이는 것이다.
→ 따라서, 우선, Receipts 테이블에 대한 접근을 1회로 줄여야 한다.
ROW_NUMBER로 각 사용자의 구매 이력에 번호를 붙임으로써, seq 필드의 최솟값을 동적으로 구하기 위해서 서브쿼리를 사용해야 했던 문제를 해결하여 테이블 접근을 1회로 줄일 수 있다.
또한, 윈도우 함수를 사용해서 결합을 제거함으로써 성능의 안전성도 확보할 수 있다.
3.
장기적 관점에서의 리스크 관리
서브쿼리와 같은 결합을 사용하는 방식은 다음과 같은 불안정 요소를 가지고 있다.
옵티마이저에 의해서 결합 알고리즘이 변경되면 성능이 변화될 수 있다.
항상 결합 키에 인덱스가 존재하지는 않으며, TEMP 탈락에 대비해 작업 메모리를 늘리는 것 또한 트레이드오프가 있다.
따라서, 엔지니어는 기능뿐만 아니라 성능도 고려해서 옵티마이저가 이해하기 쉬운 쿼리를 작성해야 한다.

22강. 서브쿼리 사용이 더 나은 경우

결합할 때는 최대한 결합 대상 레코드 수를 줄이는 것이 중요하다.
1:N의 관계를 가지고 있는 회사 테이블과 사업소 테이블을 사용해서, 각 회사마다 주요 사업소의 직원 수를 구해야 한다.
1.
결합을 한 뒤에 집약하는 방법
2.
집약을 한 뒤에 결합하는 방법
두 방법은 같은 결과를 내므로 기능적으로 같고, 가독성 면에서도 큰 차이가 없다.
하지만, 성능에서 차이가 난다.
결합 후 집약
집약 후 결합
결합 후 집약하는 방식은 회사 테이블과 사업소 테이블의 레코드를 모두 결합해야 하기 때문에 결합 대상 레코드는 두 테이블의 레코드 수를 더한 값이다.
집약 후 결합하는 방식은 사업소 테이블을 집약하여 레코드 수가 4개로 감소했기 때문에 결합 대상 레코드가 비교적 적다.
결합 대상 레코드 수에 따른 성능 차이는 테이블의 규모가 클수록 더욱 차이가 난다.
단순히 결합과 집약이라는 두 연산의 순서를 바꿈으로써 쿼리의 성능을 개선할 수 있다.

요약

서브쿼리를 사용하지 않으면 해결할 수 없는 상황도 많기에, 무작정 서브쿼리를 사용하는 것이 안 좋은 것은 아니다.
하지만, 서브쿼리는 집합을 세세한 부분으로 나누고 이들을 조합해서 결과 집합을 만들어내는 BOTTOM-UP 방식이기 때문에 비절차 지향형 언어인 SQL과 지향하는 바가 다르다는 점을 고려해야 한다.
SQL 성능을 결정하는 요인은 I/O가 절대적이다.
→ 때문에 결합을 줄이는 것이 중요하다.
성능 개선을 위해서 서브쿼리와 결합을 윈도우 함수로 대체하는 것을 고려해보자
서브쿼리를 사용할 때는 결합 대상 레코드 수를 사전에 압축함으로써 성능을 개선할 수 있다.