차집합 : SELECT - NOT IN 과 LEFT OUTER JOIN

K PizzaCola·2021년 6월 3일
0

Database

목록 보기
1/2
post-thumbnail

예시 테이블 구성

airbnb 클론 프로젝트를 하면서, 내가 원하는 체크인 - 체크아웃 기간 동안에 예약 가능한 숙소를 찾기 위한 쿼리를 작성해야 했다. 이때 테이블은 다음과 같았다.

place {
  place_id,
  ...
}

reservation {
  reservation_id,
  place_id,
  check_in,
  check_out,
  ...
}

여기서 원하는 체크인 - 체크아웃 기간 동안 예약할 수 있는 장소를 찾기 위해서 다음과 같은 쿼리를 작성하였다.

NOT IN

SELECT ... FROM place WHERE place_id NOT IN (SELECT place_id FROM reservation WHERE 조건);

스택 오버플로우에서 찾은 것인데, 서브쿼리를 이용하여 먼저 원하는 기간 동안에 예약하지 못하는 예약들에 대해서 찾은 후, NOT IN을 이용하여 포함하지 않은 결과들을 선택하는 쿼리이다. 내용 자체는 매우 직관적인 쿼리이지만, 서브쿼리를 사용하는 경우에 성능이 좋지 못할 수 있다고 한다.

그래서 관련 이야기를 찾아봤는데, MySQL의 경우, NOT IN

  • Materialization
  • EXISTS strategy

의 방식으로 최적화를 진행한다고 한다. MySQL 5.7 문서지만, 8.0에도 거의 비슷한 내용이 담겨있다.

LEFT OUTER JOIN

SELECT ... FROM place p LEFT JOIN reservation r on p.place_id = r.place_id AND 조건 WHERE r.reservation_id IS NULL;

한편, 서브쿼리의 경우 왠만하면 조인으로 해결할 수 있다고 하고, 그 경우가 성능도 더 뛰어나다고 한다. Real MySQL에서, NOT IN은 위와 같은 조인 쿼리로 바꿀 수 있다고 한다.

간단히 설명하면, 조건에 맞는 reservation을 place에 조인하고서, WHERE절로 조인이 되지 않은 결과만을 가져오는 것이다.

한편...

이와 관련해서 여러가지 찾아보는 중에, 차집합 구하기, 어떤 쿼리가 좋을까? 라는 글을 보게 되었다. 근데 아직 DB / SQL에 대해서 이해가 부족하여 읽어보기만 하였다. 오래된 글이기도 하고, 현재의 MySQL와 MS SQL하고는 다를 수도 있다. DB / SQL을 좀 더 공부해야겠다.

참고자료

profile
공부하는 개발자입니다.

0개의 댓글