[SQL] NOT EXISTS vs LEFT OUTER JOIN

리미·2020년 7월 30일
0

PostgreSQL

목록 보기
2/2
post-thumbnail

ORM을 짜기 전에 SQL문을 먼저 짜는 편

Django 프로젝트를 진행하고 있는 나는 ORM을 짜기 전에 SQL문을 먼저 짜는 편이다. ORM에 익숙해 질때쯤엔 간단한거면 그냥 바로 ORM으로 짰었는데,(프로젝트기간 좀 nullnull하게주세여) SQL을 먼저 짜고 DataGrip에서 돌려보고 ORM으로 바꾸는게 더 정확도가 높은거 같아서 요즘은 되도록이면 SQL부터 짜고 해볼려고 하고있다. 이게 좀 귀찮긴 한데 나름 debug toolbar에서 나오는 SQL이랑 내가 짠 SQL이랑 동일한지 비교하는 것도 재미있다.(정답을 맞춘 느낌)

Case 1. LEFT OUTER JOIN


JOIN 성애자인 나는 일단 JOIN 부터하고 시작했다.
Reservation 테이블과 RR(RequestReservation) 테이블의 차집합을 구하는 것인데
둘이 1:N의 관계라서 저렇게 짜봤다.

문득 든 생각 좀더 간단하게 짤수있지않을까? 라는 생각에 DBA한테 문의해보았다

말한 구문으로 한번 짜본다.

Case 2. NOT EXISTS


쿼리 하나에 끝이 나버렸다.
솔직히 NOT IN은 알고 있었는데, NOT EXISTS는 처음 사용해본다.
그렇지만 성능이 두개중에 좋은게 뭐지?

서브쿼리냐 조인이냐 그것이 문제로다

!!!!![ 뇌피셜주의 ]!!!!!
대충 SQL 최적화 관련 책을 봤을땐 서브쿼리를 사용하는게 성능저하의 원인이라고 했었다.
(사실 이 내용만 기억함)
그치만 다시 생각해보면 JOIN으로 많은 데이터를 끌고와서 WHERE로 잘라내는것도 데이터가 많아진다는 가정하에 성능저하가되지않을까? 라는 생각이 들었다

앞에서 본 DBA를 하고있는 분에게 물어보도록한다.

믿었던 DBA도 잘모른다고한다(슬슬 이분 실력이 의심이됨)

그래서 찾아본다 성능

PostgreSQL

일단 내가 현재 프로젝트에서 사용하고 있는 PostgreSQL 관점에서 살펴보겠다.
NOT EXISTS와 LEFT OUTER JOIN 모두 실행하면 PostgreSQL에서 ANTI JOIN 이란 걸 실행한다고한다.
참고 : https://explainextended.com/2009/09/16/not-in-vs-not-exists-vs-left-join-is-null-postgresql/
결국 수행계획이 동일하니 성능도 동일하다는데, 이것도 색인이 어떻게 되어있느냐, 데이터 양이 어느정도냐에 따라다를것같아서 찾아본다 datagrip 수행계획

NOT EXISTS 수행계획

수행한 쿼리는 다음과 같다

상위 쿼리에 대한 수행계획

LEFT OUTER JOIN 수행계획

수행한 쿼리는 다음과 같다

상위 쿼리에 대한 수행계획 *같은 이미지 아님

결국 NOT EXISTS 수행계획과 LEFT OUTER JOIN 수행계획이 동일하니 성능도 동일할것으로 생각된다.

MS-SQL

요즘엔 NOT EXISTS가 조금 더 빠르다고 한다.
지금 쓰고있는 DB가 PostgreSQL이라 수행계획은 직접 돌려보지않았지만,
다른 DB는 이렇다 더라~~를 담고싶었다.
참고 : https://qastack.kr/dba/121034/best-practice-between-using-left-join-or-not-exists

[추가] - 2020.08.04 ver
MS-SQL을 사용중인 그 DBA가 돌려본 결과
MS-SQL에서도 수행계획이 같다고한다
이정도면 그냥 취향으로 골라서 쓰면될듯하다

profile
Python이 하고싶은데 자꾸 Flutter 시켜서 빡쳐서 만든 블로그

1개의 댓글

comment-user-thumbnail
2021년 4월 4일

안녕하세요! 수행계획 기준으로 명확히 알려주셔서 도움받고 갑니다.
수행계획이 저렇게 시각화된 걸 처음 보는데요, 혹시 어떤 도구 사용하신 건지 알 수 있을까요?

답글 달기