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

프로그래머스 - 헤비 유저가 소유한 장소 (SQL)

programmers.co.kr/learn/courses/30/lessons/77487

 

코딩테스트 연습 - 헤비 유저가 소유한 장소

PLACES 테이블은 공간 임대 서비스에 등록된 공간의 정보를 담은 테이블입니다. PLACES 테이블의 구조는 다음과 같으며 ID, NAME, HOST_ID는 각각 공간의 아이디, 이름, 공간을 소유한 유저의 아이디를

programmers.co.kr

총 3가지 방식으로 풀어 보았습니다.

 

1. 집계함수 COUNT + PARTITION BY

실행계획을 보면 메인 쿼리와 서브 쿼리 둘다 인덱스를 타지 않고 풀스캔을 하고 둘다에서 filesort가 발생한다.

3가지 방법 중 성능이 가장 별로일거라고 생각이 든다.

SELECT PL.ID, PL.NAME, PL.HOST_ID
FROM 
    (
        SELECT * , COUNT(*) OVER (PARTITION BY HOST_ID) AS HOST_COUNT
        FROM PLACES
    ) PL
WHERE PL.HOST_COUNT > 1
ORDER BY PL.ID;

 

2. GROUP BY + IN절

메인 쿼리는 INDEX 스캔을 사용하고 filesort또한 발생하지 않는다.

IN절은 존재하는 값을 전부 확인한다는 점에서 아래에서 사용한 EXISTS보다 성능이 낮을 것으로 생각이 된다.

SELECT *
FROM PLACES PL1 
WHERE PL1.HOST_ID IN (
                        SELECT HOST_ID
                        FROM PLACES
                        GROUP BY HOST_ID
                        HAVING COUNT(*) > 1
                     )
ORDER BY ID;

 

3. GROUP BY + EXISTS

IN절을 사용했을 때와 다른점은 서브쿼리의 WHERE에 의한 차이이며

EXISTS는 해당 값의 존재 여부만 체크하므로 3가지 중 가장 좋은 성능을 보일 것으로 생각이 된다.

SELECT *
FROM PLACES PL1 
WHERE EXISTS (
                SELECT 1
                FROM PLACES PL2
                WHERE PL1.HOST_ID = PL2.HOST_ID            
                GROUP BY HOST_ID
                HAVING COUNT(*) > 1
             )
ORDER BY ID;