코딩 테스트/프로그래머스

프로그래머스 - 우유와 요거트가 담긴 장바구니 (SQL)

https://programmers.co.kr/learn/courses/30/lessons/62284

 

코딩테스트 연습 - 우유와 요거트가 담긴 장바구니

CART_PRODUCTS 테이블은 장바구니에 담긴 상품 정보를 담은 테이블입니다. CART_PRODUCTS 테이블의 구조는 다음과 같으며, ID, CART_ID, NAME, PRICE는 각각 테이블의 아이디, 장바구니의 아이디, 상품 종류, 가

programmers.co.kr

3가지 방식으로 풀 수 있습니다.

앞선 문제들에서 전체 체크하는 IN절보다 EXISTS가 좋을 수 있다고 말해왔는데

그럼 3번째 방식인 조인과는 어떻게 될까요?

 

3번째 방식의 문제는 서브쿼리를 2개 사용하면서 임시 테이블을 2개 사용하게 된다는 점인데

서브쿼리 최적화가 좋지 못한 DB나 버전에서 좋지 않을 수 있습니다.

그러나

서브쿼리 최적화를 배제하고 보면 데이터가 많아질수록 조인이 좋아질 수 있습니다.

이유는 조인 쿼리의 경우 2개의 임시테이블을 만들고 NL조인을 하게 되는데 이 경우 각각 임시 테이블이 조건에 맞는 테이블로 걸러져서 만들어지기 때문에

조인대상이 되는 두 테이블의 row 수가 확실하게 작아 질 수 있기 때문에 cost가 작아질 수 있습니다.

 

물론 실제 테이블에 절반은 요거트이고 절반은 우유라면 또 다르게 됩니다.

 

이처럼 데이터가 많냐 적냐, 버전, DB종류, 카디널리티 높냐 낮냐 등 많은 것에 의해서 적절한 쿼리문 달라질 수 있습니다.

 

개인적으로 성능이 나와야하는 경우 최대한 예상하고 실행계획을 확인하는게 좋으며 쉽게 예상되지않는다면 조회쿼리정도는 실 데이터 위에서 날려서 걸리는 시간 체크하는것도 ㅎ 

 

1. IN 절

SELECT CART_ID
FROM CART_PRODUCTS
WHERE NAME = 'Yogurt'
AND CART_ID IN (SELECT CART_ID FROM CART_PRODUCTS WHERE NAME = 'Milk')
ORDER BY CART_ID

 

1. EXISTS

SELECT CART_ID
FROM CART_PRODUCTS CP1
WHERE 
    NAME = 'Yogurt'
AND 
    EXISTS(
        SELECT 1
        FROM CART_PRODUCTS CP2
        WHERE
            CP1.CART_ID = CP2.CART_ID
        AND 
            NAME = 'Milk')
ORDER BY CART_ID

3.  조인

SELECT CP1.CART_ID
FROM
    (SELECT CART_ID FROM CART_PRODUCTS WHERE NAME = 'Milk') CP1,
    (select CART_ID FROM CART_PRODUCTS WHERE NAME = 'Yogurt') CP2
where CP1.CART_ID = CP2.CART_ID
ORDER BY CP1.CART_ID