Django 프로젝트를 진행하고 있는 나는 ORM을 짜기 전에 SQL문을 먼저 짜는 편이다. ORM에 익숙해 질때쯤엔 간단한거면 그냥 바로 ORM으로 짰었는데,(프로젝트기간 좀 nullnull하게주세여) SQL을 먼저 짜고 DataGrip에서 돌려보고 ORM으로 바꾸는게 더 정확도가 높은거 같아서 요즘은 되도록이면 SQL부터 짜고 해볼려고 하고있다. 이게 좀 귀찮긴 한데 나름 debug toolbar에서 나오는 SQL이랑 내가 짠 SQL이랑 동일한지 비교하는 것도 재미있다.(정답을 맞춘 느낌)
JOIN 성애자인 나는 일단 JOIN 부터하고 시작했다.
Reservation 테이블과 RR(RequestReservation) 테이블의 차집합을 구하는 것인데
둘이 1:N의 관계라서 저렇게 짜봤다.
문득 든 생각 좀더 간단하게 짤수있지않을까? 라는 생각에 DBA한테 문의해보았다
말한 구문으로 한번 짜본다.
쿼리 하나에 끝이 나버렸다.
솔직히 NOT IN은 알고 있었는데, NOT EXISTS는 처음 사용해본다.
그렇지만 성능이 두개중에 좋은게 뭐지?
!!!!![ 뇌피셜주의 ]!!!!!
대충 SQL 최적화 관련 책을 봤을땐 서브쿼리를 사용하는게 성능저하의 원인이라고 했었다.
(사실 이 내용만 기억함)
그치만 다시 생각해보면 JOIN으로 많은 데이터를 끌고와서 WHERE로 잘라내는것도 데이터가 많아진다는 가정하에 성능저하가되지않을까? 라는 생각이 들었다
앞에서 본 DBA를 하고있는 분에게 물어보도록한다.
믿었던 DBA도 잘모른다고한다(슬슬 이분 실력이 의심이됨)
그래서 찾아본다 성능
일단 내가 현재 프로젝트에서 사용하고 있는 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가 조금 더 빠르다고 한다.
지금 쓰고있는 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에서도 수행계획이 같다고한다
이정도면 그냥 취향으로 골라서 쓰면될듯하다
안녕하세요! 수행계획 기준으로 명확히 알려주셔서 도움받고 갑니다.
수행계획이 저렇게 시각화된 걸 처음 보는데요, 혹시 어떤 도구 사용하신 건지 알 수 있을까요?