서브쿼리

양시준·2022년 2월 21일
0

SQL 레벨업

목록 보기
7/10
post-thumbnail

7장 서브쿼리

SQL 레벨업이라는 도서를 정리한 내용입니다.

7장에서는 서브쿼리를 사용할 때의 문제와 사용하면 좋은 경우를 다룹니다. 코드 위주의 내용이지만 정리가 너무 길어지다 보니 본문에는 코드가 들어있지 않습니다.

  • 테이블 : 영속적인 테이블을 저장한다.
  • 뷰 : 영속적이지만 테이터는 저장하지 않는다. 따라서 접근할 때마다 SELECT 구문이 실행된다.
  • 서브쿼리 : 비영속적이며, 생존기간이 SQL 구문 실행 중으로 한정된다.

서브쿼리가 일으키는 폐해

서브쿼리의 문제점

연산비용 추가

서브쿼리에 접근할 때마다 SELECT 구문을 실행해 데이터를 만들어야 한다. 따라서 SELECT 구문 실행에 발생하는 비용이 추가된다. 서브쿼리의 내용이 복잡하면 복잡할수록 이러한 실행비용은 높아진다.

데이터 I/O 비용 발생

연산 결과를 어딘가에 저장해야 한다. 메모리가 크다면 상관 없지만 부족하다면 저장소의 파일을 사용하는 경우도 있다. 이렇게 되면 저장소 성능에 따라 접근 속도가 떨어진다.

최적화를 받을 수 없음

서브쿼리로 만들어지는 데이터는 테이블과 똑같은 구조를 가진다. 하지만 테이블과는 달리 명시적인 제약이나 인덱스같이 메타 정보가 없다. 따라서 옵티마이저가 쿼리를 해석하기 위해 필요한 정보를 얻을 수 없다.

서브쿼리 의존증

서브쿼리를 사용한 코드

구입 명세 테이블이 있을 때 고객의 최초 구매 이력을 찾는 경우 서브쿼리를 사용한다면 이와같은 문제가 발생한다.

  1. 서브쿼리는 대부분 일시적인 영역에 확보되므로 오버헤드가 발생한다.
  2. 서브쿼리는 인덱스 또는 제약 정보를 가지고 있지 않아 최적화할 수 없다.
  3. 서브쿼리를 사용하면 SELECT 구를 여러 번 실행하게 되고 이는 불필요한 스캔을 유발한다.
  4. 결합을 필요로 하기 때문에 비용이 높고 실행 계획 변동 리스크가 존재한다.

이는 상관 서브쿼리도 동일하다.

윈도우 함수로 결합을 제거

윈도우 함수를 사용하면 효율적으로 개선할 수 있다.

장기적인 리스크 관리

결합을 사용한 쿼리는 다음과 같은 불안정 요소를 가진다.

  • 결합 알고리즘의 변동 리스크
  • 환경 요인에 의한 지원 리스크(인덱스, 메모리, 매개변수, ...)

따라서 결합을 사용한다면 이러한 리스크를 안아야 한다. 그러므로 가능하다면 결합을 사용하지 않는 쿼리를 작성하는게 리스크를 줄일 수 있다.

결론

서브쿼리는 유용하지만 잘못 사용한다면 불필요한 I/O나 결합을 유발하기 때문에 사용에 주의가 필요하다.

서브쿼리를 사용할 때는 다른 해결방법이 존재하지 않는지 고민해볼 필요가 있다.

서브쿼리를 사용이 더 나은 경우

서브쿼리 사용이 성능 측면에서 더 나은 경우는 결합을 사용 할 때다. 결합을 사용할 때는 최대한 결합 대상 레코드를 줄여야 한다. 그런데 옵티마이저가 이러한 것을 잘 판별하지 못할 때는 서브쿼리를 사용해 명시적으로 처리해 주는것이 좋다.

회사 테이블과 사업소 테이블이 1:N 관계를 가지고 있고 특정 사업소의 개수를 구하고 싶은 상황이라고 가정해보자.

결합 이후 집약을 하는 경우

  • 회사 테이블 : 레코드 40개
  • 사업소 테이블 : 레코드 1000개

집약 이후 결합을 사는 경우

  • 회사 테이블 : 레코드 40개
  • 사업소 테이블 : 레코드 40개

이런 경우 TEMP 탈락이 일어나지 않으면 후자가 훨신 좋은 성능을 낼 수 있을 것이다.

profile
야크 털 깎기와 러버덕 디버깅을 좋아하는 개발자

0개의 댓글