우선 서브쿼리(Subquery)란 sql내에 다른 sql이 포함되어있는 포함되어있는 쿼리를 의미합니다.
SELECT절에 포함된 서브쿼리를 스칼라 서브쿼리라고 부르는데,
스칼라 서브쿼리로 부터 나오는 결과는 반드시 하나여야합니다.(그렇지 않을 경우 에러 발생...)
SELECT business_number, (
SELECT count(*)
FROM like_store i
WHERE i.business_number = s.business_number
)
FROM stores s;
위 쿼리의 수행 순서는 메인 쿼리 -> 서브 쿼리 순으로 동작합니다.
서브쿼리는 결과 건수만큼 반복 수행되기 때문에 조회되는 데이터의 갯수가 적다면 크게 문제될 것은 없지만,
조회 되는 데이터의 갯수가 많아지면 많아질 수록 성능이 현저히 떨어지는 모습을 볼 수 있습니다.
또한 스칼라 서브쿼리 사용시 서브쿼리의 결과값이 같은 경우가 많거나, 매번 동일한 결과값을 반환한다면, 스칼라 서브쿼리의 캐싱 효과를 통해 성능을 높일 수 있으나, 서브쿼리에서 사용되는 조건의 종류가 많아지거나 혹은 조건 데이터가 지속적으로 바뀔경우 캐싱의 효율성이 떨어지기 때문에 이전보다 성능이 떨어질 수 있습니다.
위 예시 쿼리는 매번 서브 쿼리가 수행될 때마다 s.business_number(pk)가 달라지기 때문에 성능이 좋지 않은 모습을 볼 수 있었는데요.
위와 같은 서브쿼리의 성능을 개선하기 위해 LEFT OUTER JOIN에 인라인 뷰를 포함 시킬 수 있습니다.
SELECT s.business_number, IFNULL(i.count,0)
FROM stores s
LFET OUTER JOIN (SELECT COUNT(*) count, business_number
FROM interest_store
GROUP BY business_number) i
ON s.business_number = i.business_number
SELECT절에 있던 서브쿼리의 구문을 LEFT OUTER JOIN으로 옮긴 모습을 볼 수 있는데,
각 업체마다 좋아요 count를 확인할 수 있어야했기 때문에 GROUP BY절을 사용했습니다.
감사합니다 ㅎㅎ